Question

J'ai un programme qui crache un classeur Excel au format Excel 2003 XML. Cela fonctionne bien avec un problème, je ne parviens pas à définir automatiquement la largeur des colonnes.

Un extrait de ce que je produis:

  <Table >
   <Column ss:AutoFitWidth="1" ss:Width="2"/>
   <Row ss:AutoFitHeight="0" ss:Height="14.55">
    <Cell ss:StyleID="s62"><Data ss:Type="String">Database</Data></Cell>

Ceci ne configure pas la colonne sur ajustement automatique. J'ai essayé de ne pas régler la largeur, j'ai essayé beaucoup de choses et je suis coincé.

Merci.

Était-ce utile?

La solution

Seules les valeurs de date et de nombre sont ajustées automatiquement :-( quote: "... nous ne modifions pas automatiquement les valeurs textuelles"

http://msdn.microsoft.com/en- us / library / aa140066.aspx # odc_xmlss_ss: colonne

Autres conseils

Prenez la longueur de votre chaîne avant de passer à XML et construisez le fichier ss: Width = "quot".

L'ajustement automatique ne fonctionne pas sur les cellules avec des chaînes. Essayez de remplacer la ligne de colonne dans votre exemple par le code suivant:

    <xsl:for-each select="/*/*[1]/*">
      <Column>
        <xsl:variable name="columnNum" select="position()"/>
        <xsl:for-each select="/*/*/*[position()=$columnNum]">
          <xsl:sort select="concat(string-length(string-length(.)),string-length(.))" order="descending"/>
          <xsl:if test="position()=1">
            <xsl:if test="string-length(.) &lt; 201">
              <xsl:attribute name="ss:Width">
                <xsl:value-of select="5.25 * (string-length(.)+2)"/>
              </xsl:attribute>
            </xsl:if>
            <xsl:if test="string-length(.) &gt; 200">
              <xsl:attribute name="ss:Width">
                <xsl:value-of select="1000"/>
              </xsl:attribute>
            </xsl:if>
          </xsl:if>
          <xsl:if test = "local-name() = 'Sorteer'">
            <xsl:attribute name="ss:Width">
              <xsl:value-of select="0"/>
            </xsl:attribute>
          </xsl:if>
        </xsl:for-each>
      </Column>
    </xsl:for-each>

Explication: Il trie par longueur de chaîne (la plus longue en premier), prend la première ligne de chaînes triées, prend la longueur de cette chaîne * 5.25 et vous obtiendrez un ajustement automatique raisonnable.

Ligne de tri:

        <xsl:sort select="concat(string-length(string-length(.)),string-length(.))" order="descending"/>

explication: si vous venez de trier par longueur, comme

        <xsl:sort select="string-length(.)" order="descending"/>

parce que les longueurs sont traitées comme des chaînes, 2 vient après 10, ce que vous ne voulez pas. Donc, vous devez indiquer les longueurs à gauche pour que le tri soit correct (car 002 précède 010). Cependant, comme je ne pouvais pas trouver cette fonction de rembourrage, je l'ai résolue en concattenant la longueur de la longueur avec la longueur. Une chaîne d'une longueur de 100 sera traduite en 3100 (le premier chiffre est une longueur de longueur), vous verrez que la solution sera toujours triée correctement. par exemple: 2 sera " 12 " et 10 sera "210", donc ceci sera trié correctement. Seulement lorsque la longueur de la longueur > 9 causera des problèmes, mais les chaînes de longueur 100000000 ne peuvent pas être traitées par Excel.

Explantion de

            <xsl:if test="string-length(.) &lt; 201">
              <xsl:attribute name="ss:Width">
                <xsl:value-of select="5.25 * (string-length(.)+2)"/>
              </xsl:attribute>
            </xsl:if>
            <xsl:if test="string-length(.) &gt; 200">
              <xsl:attribute name="ss:Width">
                <xsl:value-of select="1000"/>
              </xsl:attribute>
            </xsl:if>

Je voulais maximiser la longueur de la chaîne à environ 200, mais je ne pouvais pas faire fonctionner la fonction Min, comme

              <xsl:value-of select="5.25 * Min((string-length(.)+2),200)"/>

Il a donc fallu que je le fasse à mauvais escient.

J'espère que vous pourrez vous ajuster automatiquement maintenant!

Je sais que ce message est ancien, mais je le mets à jour avec une solution que j'ai codée si quelqu'un utilise encore openXml. Cela fonctionne très bien avec les gros et les petits fichiers.

L’algorithme est en vb, il faut un arrayliste d’arraylist ou une chaîne (modifiable en fonction des besoins) pour matérialiser un tableau Excel.

J'ai utilisé un formulaire Windows pour trouver la largeur du texte rendu et des liens pour sélectionner uniquement les cellules les plus grandes (pour l'efficacité des gros fichiers)

Là-bas:

Dim colsTmp as ArrayList '(of Arraylist(of String))
Dim cols as Arraylist '(of Integer) Max size of cols
'Whe populate the Arraylist
Dim width As Integer
'For each column
For i As Integer = 0 To colsTmp.Count - 1
    'Whe sort cells by the length of their String
    colsTmp(i) = (From f In CType(colsTmp(i), String()) Order By f.Length).ToArray
    Dim deb As Integer = 0
    'If they are more than a 100 cells whe only take the biggest 10%
    If colsTmp(i).length > 100 Then
        deb = colsTmp(i).length * 0.9
    End If
    'For each cell taken
    For j As Integer = deb To colsTmp(i).length - 1
        'Whe messure the lenght with the good font and size
        width = Windows.Forms.TextRenderer.MeasureText(colsTmp(i)(j), font).Width
        'Whe convert it to "excel lenght"
        width = (width / 1.42) + 10
        'Whe update the max Width
        If width > cols(i) Then cols(i) = width
    Next
Next
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top