文章目录
- 👉一、前言
- 👉二、问题重现
- 1、首先看一下我用下面两段代码创建的表格:
- 2、被这个问题折磨的心路历程
- 👉三、分析原因
- 👉四、解决方法
👉一、前言
最近在使用Aspose.Words.dll实现创建表格功能时,遇到了一个让我费解了好几天的问题——单元格垂直合并失效。我都快要怀疑人生了都,关键是它水平合并没问题,而且创建别的表格垂直合并也没问题;况且经过我反复测试,代码逻辑也是没有问题的,你说这气不气人,都快被我整出玄学来了。功夫不负有心人,终于在一个周末让我找到了问题的关键所在,最终解决了这个Aspose.Words创建表格单元格垂直合并失效的问题。仅以此博客记录,供新同学学习,避免踩坑!
👉二、问题重现
1、首先看一下我用下面两段代码创建的表格:
绘制表格前需要引用的命名空间:
using Aspose.Words;
using Aspose.Words.Tables;
测试表格1:
string docPath = "xxxx";//doc模板文件的路径
Document doc = new Document(docPath);
DocumentBuilder builder = new DocumentBuilder(doc);//绘制文档内容的一支笔
Table testTable = builder.StartTable();//开始绘制表格
for (int i = 0; i < 4; i++)
{
builder.InsertCell();//绘制一个单元格
if (i == 0)
{
//水平合并第一个单元标记为First
builder.CellFormat.HorizontalMerge = CellMerge.First;
builder.Write("测试表头水平合并单元格");
}
else
{
//将后面需要水平合并的单元格标记为Previous
builder.CellFormat.HorizontalMerge = CellMerge.Previous;
}
}
builder.EndRow();//结束一行
builder.CellFormat.HorizontalMerge = CellMerge.None;
for (int i = 0; i < 8; i++)
{
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.None;
int cellIdx = (i > 3) ? (i - 4) : i;//用来计算单元格在一行中的下标位置
if (cellIdx == 0 || cellIdx == 1)//下标为0或1的需要垂直合并
{
if (i < 4)
{
builder.CellFormat.VerticalMerge = CellMerge.First;
}
else
{
builder.CellFormat.VerticalMerge = CellMerge.Previous;
}
}
builder.Write("测试单元格合并" + i);
if (cellIdx == 3)
{
builder.EndRow();
}
}
builder.EndTable();//结束一个表格
testTable.AllowAutoFit = false;//不允许自适应内容重调尺寸
测试表格2:
Table testTable2 = builder.StartTable();
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.First;
builder.Write("第一行第一列垂直合并");
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.First;
builder.Write("第一行第二列垂直合并");
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.None;
builder.Write("第一行第三列不合并");
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.None;
builder.Write("第一行第四列不合并");
builder.EndRow();
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.Previous;
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.Previous;
builder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.None;
builder.Write("第二行第三列不合并");
hbuilder.InsertCell();
builder.CellFormat.VerticalMerge = CellMerge.None;
builder.Write("第二行第四列不合并");
builder.EndTable();
2、被这个问题折磨的心路历程
1.两个绘制表格的代码都是放在一起的,绘制完上一个,就绘制一个了,怎么会出现这种情况呢?郁了个大闷。最开始我还以为是我绘制表格的逻辑写错了,但经过我反复测试代码逻辑肯定是没错的。
2.后面我就怀疑是不是这个Aspose.Words.dll版本的问题,于是我又找了这个版本前后的好几个版本导进来测试也是会出现这个问题,所以也排除了这个原因。
3.由于我用的Unity版本有点低,我在想会不会是Unity版本低的原因这个Api它不支持所以失效呢,后面也排除了。
反反复复换了一些方法,也调试代码测试,堵了好些时间都没解决。
可能心细的朋友看我上面那两段代码早就发现了问题所在:第一段画表格代码比第二段多了一句不一样的代码:testTable.AllowAutoFit = false;(这个属性默认为true)
我也是被折磨了好久才发现这里的,于是我把这句话注释掉,第一个表格的垂直合并就正常了!所以说导致垂直合并失效的原因是这句代码。这个属性是用来设置表格是否可以自适应内容重调表格单元格的尺寸的。如果去掉这句,保存的表格后,如果往单元格里输入内容,单元格的宽度就会横向自适应,弄的表格不好看。所以我的需求里就必须加上这句代码(虽然打开保存后的word文件,也可以设置这个表格属性,但是为了减少用户操作)。如果我继续留这个代码那就无法绘制垂直合并的单元格,所以只能另寻他法,于是我也是一通好找,才找到了一个跟表格布局相关的Api:doc.UpdateTableLayout();,我刚开始是将这句代码放在保存文档之前,发现还是有问题,我又郁闷了,实在是没方法了,后来我想到把这句话放在绘制完表格之后试试,没想到问题解决了!最终我想清楚了这里面的原因,以及得出了解决方法。
👉三、分析原因
我猜想是因为代码里将表格设置为不允许自适应内容后,表格的一些格式设置(如单元格垂直合并)会失效;所以应该在设置AllowAutoFit这个属性前调用UpdateTableLayout()方法更新一下表格的布局,让表格其他属性先生效,再设置AllowAutoFit为false。经过反复测试也证实了,如果设置AllowAutoFit为false后,再调用UpdateTableLayout()方法也是会出现单元格垂直合并失效这个问题。以此得出下文解决方法。
👉四、解决方法
1.注释掉AllowAutoFit=false;这句代码(前提是你没有这个需求),因为它默认就是true允许自适应,只是这样会导致输入内容时列宽自动扩充,不好看而已。没有这个需求的话也不会出现单元格垂直合并失效的问题。
2.如果不允许表格自适应,也就是设置了AllowAutoFit=false的之前,先调用UpdateTableLayout()方法刷新表格布局。
doc.UpdateTableLayout();
table.AllowAutoFit = false;
这样表格就正常了。
3.不过我看Aspose.Words的官方文档说:通常不需要调用此方法,因为单元格和表的宽度是自动维护的。可能需要在导出到PDF之前调用此方法,只有在PDF输出中出现表格布局错误的极少数情况下才需要调用此方法。目前我没有发现用这个Api会出现文档里的其他内容格式错乱的情况,所以具体就看各自的需求了。