open - Formato XML de Excel 2003-AutoFitWidth no funciona
open xml sdk tutorial (4)
Tengo un programa que escupe un libro de Excel en formato XML de Excel 2003. Funciona bien con un problema, no puedo configurar el ancho de las columnas automáticamente.
Un fragmento de lo que produzco:
<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>
Esto no configura la columna para autofit. Intenté no configurar el ancho, probé muchas cosas y estoy atascado.
Gracias.
Solo los valores de fecha y número son autofitted :-( quote: "... No autofit textual values"
http://msdn.microsoft.com/en-us/library/aa140066.aspx#odc_xmlss_ss:column
Tome su longitud de cadena antes de pasar a XML y construir el ss: Width = "length".
Autofit no funciona en celdas con cadenas. Intenta reemplazar la línea de columna en tu ejemplo por el siguiente código:
<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(.) < 201">
<xsl:attribute name="ss:Width">
<xsl:value-of select="5.25 * (string-length(.)+2)"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="string-length(.) > 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>
Explicación: ordena en longitud de cadena (la cadena más larga primero), toma la primera línea de cadenas ordenadas, toma la longitud de esa cadena * 5.25 y obtendrás una configuración automática razonable.
Línea de clasificación:
<xsl:sort select="concat(string-length(string-length(.)),string-length(.))" order="descending"/>
explicación: si solo ordena la longitud, como
<xsl:sort select="string-length(.)" order="descending"/>
porque las longitudes se manejan como cadenas, 2 viene después de 10, que no desea. Por lo tanto, debe dejar el margen izquierdo para que quede bien ordenado (porque 002 viene antes del 010). Sin embargo, como no pude encontrar esa función de relleno, la resolví concatenando la longitud de la longitud con la longitud. Una cadena con una longitud de 100 se traducirá a 3100 (el primer dígito es la longitud de la longitud), verá que la solución siempre será ordenada por cadenas. por ejemplo: 2 será "12" y 10 será "210", por lo que se ordenará correctamente. Sólo cuando la longitud de la longitud> 9 causará problemas, pero Excel no puede manejar cadenas de longitud de 100000000.
Explicación de
<xsl:if test="string-length(.) < 201">
<xsl:attribute name="ss:Width">
<xsl:value-of select="5.25 * (string-length(.)+2)"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="string-length(.) > 200">
<xsl:attribute name="ss:Width">
<xsl:value-of select="1000"/>
</xsl:attribute>
</xsl:if>
Quería maximizar la longitud de la cadena a aproximadamente 200, pero no pude hacer funcionar la función Min, como
<xsl:value-of select="5.25 * Min((string-length(.)+2),200)"/>
Así que tuve que hacerlo de la manera sucia.
¡Espero que puedas autoajustar ahora!
Sé que esta publicación es antigua, pero la actualizo con una solución que codifiqué si alguien todavía usa openXml. Funciona bien con archivos grandes y pequeños.
El algoritmo está en vb, toma una lista de arrays de una lista de cadenas (se puede cambiar según las necesidades) para materializar una matriz de Excel.
Utilicé un formulario de Windows para encontrar el ancho del texto renderizado, y enlaces para seleccionar solo las celdas más grandes (para la eficiencia de los archivos grandes)
Ahí:
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