12

我有一个程序可以输出 Excel 2003 XML 格式的 Excel 工作簿。它可以很好地解决一个问题,我无法自动设置列宽。

我制作的片段:

  <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>

这不会将列设置为自动调整。我试过不设置宽度,我尝试了很多东西,但我被卡住了。

谢谢。

4

4 回答 4

28

只有日期和数字值是自动调整的 :-( quote: "... We do not autofit textual values"

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

于 2008-10-05T14:22:21.533 回答
2

在传递给 XML 之前获取您的字符串长度并构造 ss:Width="length"。

于 2013-11-11T17:17:21.157 回答
0

Autofit 不适用于带有字符串的单元格。尝试用以下代码替换示例中的 Column-line:

    <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>

说明:它按字符串长度排序(最长的字符串优先),取第一行排序的字符串,取该字符串的长度 * 5.25,你将有一个合理的自动调整。

分拣线:

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

解释:如果你只是按长度排序,比如

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

因为长度是作为字符串处理的,所以 2 在 10 之后,这是您不想要的。所以你应该左填充长度以使其正确排序(因为 002 在 010 之前)。但是,由于我找不到该填充功能,我通过将长度的长度与长度连接来解决它。长度为 100 的字符串将被转换为 3100(第一个数字是长度的长度),您将看到解决方案将始终正确地进行字符串排序。例如:2 将是“12”,10 将是“210”,所以这将是正确的字符串排序。只有当length的长度> 9时才会出现问题,但是Excel无法处理长度为100000000的字符串。

的解释

            <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>

我想将字符串的长度最大化到大约 200,但我无法让 Min 函数工作,比如

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

所以我不得不用肮脏的方式来做。

我希望你现在可以自动调整!

于 2014-09-25T19:12:33.933 回答
0

我知道这篇文章很旧,但是如果有人仍在使用 openXml,我将使用我编写的解决方案对其进行更新。它适用于大文件和小文件。

该算法在vb中,它需要一个arraylist of arraylist of string(可根据需要更改)来实现一个excel数组。

我使用 Windows 窗体来查找渲染文本的宽度,以及仅选择最大单元格的链接(以提高大文件效率)

那里:

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
于 2017-07-10T15:32:07.953 回答