【问题标题】:RowHeight anomaly from Spreadsheetgear and Excel来自 Spreadsheetgear 和 Excel 的 RowHeight 异常
【发布时间】:2014-06-11 05:12:53
【问题描述】:

我正在使用 Spreadsheetgear 以编程方式制作 excel,但我有一个与行高相关的问题。

我在 C# 中有这个 sn-p 代码

cells[0, 0].ColumnWidth = totalColumnWidth; // recalculated column width after some formatting logic
var x = cells[0, 0].RowHeight; // gives me 14.95
cells[0, 0].Formula = "A long long text goes here spanning multiple lines..."; // spanning say 10 rows in excel
x = cells[0, 0].RowHeight; // gives me 190.5

当我保存这个 excel,并在 MS Excel 中打开它时,我可以看到行高是 210。

对于一个空的 excel 工作表,我从电子表格中获得的行高为 14.95,而从 excel 中获得的行高为 15。 我也分别得到 8.09 和 8.43 的列宽。

我的问题是 - 为什么这两个数字的来源有区别?在处理这些问题时,我是否应该考虑某种软糖因素?谢谢!

【问题讨论】:

    标签: c# vba excel spreadsheetgear


    【解决方案1】:

    除非您明确指定某些行的高度值(以磅为单位),否则行高将根据工作簿的默认字体高度自动确定(请参阅 IWorkbook.Styles["Normal"].Font)。

    与此相关,列宽以“字符单位”测量。字符单位不是绝对的度量单位;它们还依赖于工作簿的默认字体。这就是您为列宽指定值(例如 8)的原因。使用工作簿的默认字体,“字符单位”大致等于“0”字符的宽度。请注意,在此之上添加了一些填充,因此您的实际列宽仍将略宽于 8 个字符。

    对于自动行高和列宽,SpreadsheetGear 与 Excel 的单位不完全匹配,因为 SpreadsheetGear 依赖 GDI+/WPF/Silverlight 图形库来测量字体的高度和“字符单位”值,而 Excel 使用本机 GDI 来测量这些事物。不幸的是,对于相同的给定文本,每个库计算的结果略有不同,因此您会遇到列宽和自动行高的细微差异。除非 SpreadsheetGear 与 Excel 在完全相同的环境中运行(即使用 GDI),否则这些差异是不可避免的。

    在 SpreadsheetGear 中自动调整列时经常会出现此问题。虽然带有 AutoFitted 文本的工作簿将在我们自己的 WorkbookView 控件中呈现得很好,但将工作簿保存到磁盘然后在 Excel 中打开生成的工作簿通常会导致列稍微太短。列宽越宽,这一点就越明显。因此,客户在 Excel 中查看工作簿时,通常必须添加一个轻微的“捏造因素”才能获得预期的结果。

    可以手动设置行高,以磅为单位。因此,如果您不介意手动设置完全不会改变的行高,尽管单元格包含内容,您可以考虑将行显式设置为同时适应 Excel 和 SpreadsheetGear 的高度。

    实际上,在使用我们的 WorkbookView 控件时,您会发现在很多情况下,SpreadsheetGear 与自身的一致性比 Excel 更一致,这是因为我们使用了更可靠的字体度量。即使在 Excel 本身中自动调整,不使用 SpreadsheetGear,通过保存然后加载到具有不同屏幕 DPI(96 / 120 / 等...)的机器上,也会出现列宽差异。再举一个例子,尝试在 Excel 2007/2010/2013 的单元格中输入一个很长的文本字符串,自动调整文本,然后使用右下角的滑块工具放大或缩小,注意文本可能不适合某些设置(它会适合某些文本,但很少见)。这种不一致的行为在 SpreadsheetGear 中不会发生。

    【讨论】:

      【解决方案2】:

      我对蒂姆的答案没有任何批评,我已投票赞成以使其成为第一个答案。我同意他关于 Excel 不一致的 cmets 和他关于 SpreadsheetGear 的 cmets 显然是权威的。这个答案是附加信息,如果您决定需要一个软糖因素,可能会很有用。

      在 Excel 中,如果您将鼠标悬停在行边界上,您将看到行高为 12.75 (17 pixels)19.5 (26 pixels) 或类似的东西。我尝试手动调整行高并更改默认字体和/或大小。我找不到任何 points * 4/3 = pixels 不正确的行高。

      悬停在列边界上会给出不同的值,例如 8.43 (64 points)11.52 (86 pixels)。点和像素值之间的关系不同,但似乎仍然是固定的。下面的例程给出了从像素到点的转换,这对于我尝试过的每个值都是正确的。该例程是用 VB.Net 编写的,但如果您有兴趣,它将很容易转换为 C#。

      Private Shared Function pixelsToPoints(ByVal pixels As Integer) As Double
      
        ' Converts a column width in pixels to points.
      
        '  Pixels   Points
        '       0      0.0
        ' 0<=N<12      points1(N)
        '      12      1.0
        '      19      2.0
        '      26      3.0
        '   N>=12      (N - 12) Mod 7 + 1 + points2((N - 12) \ 7)  
      
        ' Point increments between pixel = 2 and pixels = 11 
        Dim points1() As Double = {0.0, 0.08, 0.17, 0.25, 0.33, 0.42, 0.5, 0.58, 0.67, 0.75, 0.83, 0.92}
        ' Point increments above pixels = 12 
        Dim points2() As Double = {0.0, 0.14, 0.29, 0.43, 0.57, 0.71, 0.86}
      
        Select Case pixels
          Case Is < 12
            Return points1(pixels)
            Exit Function
          Case Is >= 12
            Dim pixelsTemp As Integer = pixels - 12
            Dim pointsTemp As Double = 1.0
            pointsTemp += (pixelsTemp) \ 7 + points2(pixelsTemp Mod 7)
            Return pointsTemp
            Exit Function
        End Select
      
        Return 0.0      ' Required to avoid warning
      
      End Function
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-26
        • 1970-01-01
        • 2011-08-13
        • 1970-01-01
        • 2021-05-05
        • 1970-01-01
        • 2014-12-16
        相关资源
        最近更新 更多