Формат Excel 2003 XML - AutoFitWidth не работает

У меня есть программа, которая выдает книгу Excel в формате Excel 2003 XML. Он отлично работает с одной проблемой, я не могу настроить ширину столбцов автоматически.

Фрагмент того, что я делаю:

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

Это не устанавливает для столбца автоподбор. Я пробовал не устанавливать ширину, я пробовал много вещей, и я застрял.

Спасибо.


person Peter    schedule 05.10.2008    source источник


Ответы (4)


Автоматически подбираются только значения даты и числа :-( цитата: "... Мы не подбираем автоматически текстовые значения"

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

person Community    schedule 05.10.2008
comment
Можно задаться вопросом, почему, поскольку Excel может очень хорошо автоматически подгонять текстовые столбцы. - person MSC; 21.01.2019

Возьмите длину строки перед передачей в XML и создайте ss:Width="length".

person supermankelly    schedule 11.11.2013
comment
Любая идея, почему ss:Width не имеет никакого отношения к единицам, используемым в самом Excel? Например, я указываю ss:Width: 200, что отображается в Excel как ширина столбца 37,43. Это не пиксели, так каковы единицы измерения ss:Width? - person MSC; 21.01.2019

Автоподбор не работает в ячейках со строками. Попробуйте заменить 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", поэтому это будет правильно отсортировано по строкам. Проблемы возникнут только тогда, когда длина > 9 вызовет проблемы, но строки длиной 100000000 не могут быть обработаны Excel.

Эксплантация

            <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)"/>

Поэтому мне пришлось сделать это грязным способом.

Я надеюсь, что вы можете автофит теперь!

person Mathijs Beentjes    schedule 25.09.2014

Я знаю, что этот пост устарел, но я обновляю его решением, которое я закодировал, если кто-то все еще использует openXml. Он отлично работает с большими файлами и маленькими файлами.

Алгоритм находится в vb, для материализации массива 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
person m.nachury    schedule 10.07.2017