来自Spreadsheetgear和Excel的RowHeightexception

我正在使用Spreadsheetgear以编程方式创buildexcel,并且我有一个与行高有关的问题。

我有这个代码片段在C#

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。

我的问题是 – 为什么这两个数字之间有什么区别? 在处理这些问题时,我应该考虑一些模糊的因素吗? 谢谢!

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

相关地,列宽以“字符单位”来衡量。 字符单位不是绝对的度量单位; 他们也依赖于工作簿的默认字体。 这就是为什么你指定一个列宽为8的值。 “字符单位”大致等于使用工作簿的默认字体的“0”字符的宽度。 请注意,一些填充添加在此之上,所以您的实际列宽将仍然略宽于8个字符。

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

当在SpreadsheetGear中自动调整列时,通常会出现此问题。 虽然具有“自动配合”文本的工作簿在我们自己的WorkbookView控件中呈现得很好,但将工作簿保存到磁盘,然后在Excel中打开生成的工作簿通常会导致列太短。 列宽越宽,这变得越明显。 因此,在Excel中查看工作簿时,客户通常不得不添加轻微的“模糊因素”以获得预期的结果。

行高可以手动设置,点。 因此,如果您不介意手动设置不会改变的行高(即使单元格的内容不变),也可以考虑明确地将行设置为适合Excel和SpreadsheetGear的高度。

实际上,当使用我们的WorkbookView控件时,由于我们使用了更可靠的字体指标,因此在许多情况下,您会发现SpreadsheetGear比Excel本身更加一致。 即使在Excel本身内部自动拟合,而不使用SpreadsheetGear的情况下,也可以通过在具有不同屏幕DPI(96/120 / etc …)的机器上进行保存然后加载来发生列宽差异。 作为另一个例子,尝试在Excel 2007/2010/2013中的单元格中input一个非常长的文本string,自动调整文本,然后使用右下angular的滑块工具进行放大或缩小,并注意文本可能不会适合某些设置(这将适合某些文本,但很less见)。 这种不一致的行为在SpreadsheetGear中不会发生。

我没有批评蒂姆的答案,我曾试图把它作为第一个答案。 我同意他关于Excel的不一致的评论,他对SpreadsheetGear的评论显然是认真的。 这个答案是额外的信息,如果你决定你需要一个模糊因素,这可能是有用的。

在Excel中,如果将鼠标hover在行边界上,则会看到行高为12.75 (17 pixels)19.5 (26 pixels)或类似的东西。 我已经尝试手动调整行高,并通过更改默认的字体和/或大小。 我无法find哪个points * 4/3 = pixels高度points * 4/3 = pixels是不正确的。

hover在列边界上会给出不同的值,如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