CalculateTextSizeTest.zip (86.1 KB)
public static void testHeight()
{
// Create a new workbook and save with different DPI settings
Workbook workbook = new Workbook("D:\\CalculateTextSizeTest.xlsm");
Worksheet sheet = workbook.Worksheets["产品销售情况"];
foreach (Shape shape in sheet.Shapes)
{
// 判断形状是否为文本框
if (shape is Aspose.Cells.Drawing.TextBox)
{
Aspose.Cells.Drawing.TextBox textBox = (Aspose.Cells.Drawing.TextBox)shape;
// 判断文本框的名称是否以"批注文本框"开头
if (textBox.Name.StartsWith("批注文本框"))
{
// 获取文本框的高度
double textBoxHeight = textBox.Height;
Console.WriteLine("count" + textBox.TextBody.TextParagraphs.Count);
Console.WriteLine(textBox.Text);
int[] estimatedTextHeight = textBox.CalculateTextSize();
Console.WriteLine(estimatedTextHeight[1]);
// 检查是否溢出
if (estimatedTextHeight[1] > textBoxHeight)
{
throw new OverflowException(
$"{sheet.Name}在第{textBox.Top}行,第{textBox.Left}列的文本框内容溢出,请调整内容!"
);
}
}
}
}
}
@lingtian
CalculateTextSize 的工作原理
TextBox.CalculateTextSize() 在内部调用 Aspose.Cells 的文字排版引擎,根据文本的字体、字号、字符间距以及当前工作表的 DPI(默认 96)来计算 单行文本 所占的宽度和高度,返回 int[2]([width, height])。
为什么示例中文本会溢出而返回的高度却小于文本框高度
从论坛的反馈可以看到:
- 当文本中包含换行符(
\r\n、\n)时,CalculateTextSize() 只返回 默认单行高度,不再根据实际的多行布局进行累计。
- 该问题在 8.9.x 及以后版本中仍然存在,属于 回归 bug(8.6.2 版本可以正确计算多行高度)。
因此,在您提供的 CalculateTextSizeTest.xlsm 中,文本框里的内容是多行的,实际占用的高度远大于单行高度;CalculateTextSize() 只给出了单行的高度值,导致判断为 “未溢出”,实际却已经超出文本框。
临时解决方案(不依赖 CalculateTextSize)
-
手动计算行高
// 每行的高度 = 字体大小(pt) * 1.33(约等于像素) + 行间距(如果有)
double lineHeight = textBox.Font.Size * 1.33;
int lineCount = textBox.TextBody.TextParagraphs.Count; // 或自行统计 \n 的数量 + 1
double estimatedHeight = lineHeight * lineCount;
-
去掉换行符后再调用(仅在业务允许的情况下)
string singleLine = textBox.Text.Replace("\r", "").Replace("\n", " ");
textBox.Text = singleLine;
int[] size = textBox.CalculateTextSize(); // 现在返回的高度会更接近实际
-
使用 AutoFit(如果只是想让文本框自适应)
textBox.AutoFit = true; // 让 Aspose.Cells 自动调整文本框大小
-
升级或等待修复
- 确认使用的 Aspose.Cells 版本。如果是 8.9.x 系列,建议向 Aspose 官方提交 Bug 报告(附上示例文件和复现代码),并关注后续版本的修复说明。
- 若可以接受使用更高的版本(如 23.x+),先在测试环境中验证是否已修复,再决定是否升级。
诊断信息建议提供给 Aspose 支持
| 项目 |
内容 |
| Aspose.Cells 版本 |
例如 8.9.0、8.9.0.5、23.9 等 |
| 操作系统 & .NET 运行时 |
Windows 10, .NET Framework 4.8 / .NET 6 等 |
| 示例文件 |
CalculateTextSizeTest.xlsm(已上传) |
| 复现代码 |
您提供的 testHeight() 方法 |
| 观察到的现象 |
多行文本实际溢出,CalculateTextSize()[1] 只返回单行高度 |
| 期望行为 |
返回累计的多行高度,或能够检测到溢出 |
提供上述信息后,Aspose 支持团队可以更快定位并在后续版本中修复此问题。祝您调试顺利!
@lingtian,
感谢提供模板Excel文件。
很抱歉,目前尚无精确的方法来确定确切的高度和宽度,因为文本方向、文本对齐方式以及是否启用了自动换行功能都会影响实际或原始值。无论如何,我使用您的示例文件和代码片段测试了您的场景/案例。发现当CalculateTextSize小于文本框高度时,文本确实如您所述发生了溢出现象。
我们需要对该问题进行深入评估。我们已在内部问题跟踪系统中创建了以下新工单,并将根据Free Support Policies中提到的条款提供修复。
问题ID:CELLSNET-59486
如果您需要优先支持服务以及直接访问我们的付费支持管理团队,可通过Paid Support Services获取相关支持。
@amjad.sahi
使用Microsoft.Office.Interop.Excel,以下代码可以比较准确的判断文本框中文字高度,供参考。
internal static void CheckTextBoxOverllow(Excel.Worksheet sht, List<string> listErrors)
{
foreach (var txtBox in sht.Shapes.OfType<Excel.Shape>().Where(s => s.Name.StartsWith("批注文本框")))
{
//批注文本框内容的高度和批注文本框高度比较,需要剔除上下边缘的留边大小,使用TrimText方法,可以得到清除末尾空格回车字符,不清除头部,实现了忽略末尾多余的空白字符。
var txtRangeTrim = txtBox.TextFrame2.TextRange.TrimText();
if (!string.IsNullOrEmpty(txtRangeTrim.Text) &&
Math.Floor(txtBox.Height - txtBox.TextFrame2.MarginTop - txtBox.TextFrame2.MarginBottom ) < txtBox.TextFrame2.TextRange.TrimText().BoundHeight)
{
var txtBoxRange = sht.Range[txtBox.TopLeftCell, txtBox.BottomRightCell];
listErrors.Add($"工作表:{sht.Name},文本框位置:{txtBoxRange.Address[false, false]}");
}
}
}
@lingtian
感谢你的反馈和提供的Microsoft.Office.Interop.Excel文字宽高计算信息。让我们详细调查和分析您的问题。一旦有任何更新,我们将及时通知你。