NPOI word表格实现动态组织行列

发布时间 2024-01-02 10:27:59作者: 某云

NPOI版本2.2.1

难点一:列增加

NPOI对于增加列真的很不健壮

坑一: GetCell超出索引

如果只写如下代码就以为完成了列增加

XWPFDocument doc = new XWPFDocument(stream);
var table1 = doc.Tables[0];
table1.AddNewCol();

你将在后面为新增列的单元格赋值代码中喜提GetCell超出索引的报错

因此你需要加上如下代码

XWPFDocument doc = new XWPFDocument(stream);
var table1 = doc.Tables[0];
table1.AddNewCol();
//添加grid信息使得索引信息同步
var cttbl = doc.Document.body.getTblArray()[0];
cttbl.tblGrid.AddNewGridCol();

结果你会发现,再为新增的列添加信息时还是报错了,你的新增列仍未被GetCell读取到

因此,你需要暂时把这个模板存下来记为中间模板,再去打开中间模板进行赋值操作即可

难点二:对增加的列调整列间距

坑二:操作控制列宽的属性不起效

对于增加列的列宽控制,只有如下代码,将不生效

table.SetColumnWidth(i , 600);

完整起效版如下

XWPFDocument doc = new XWPFDocument(stream);
var table1 = doc.Tables[0];

//为了设置列宽
var cttbl = doc.Document.body.getTblArray()[0];
cttbl.AddNewTblPr().tblLayout = new CT_TblLayoutType() { type = ST_TblLayoutType.@fixed };
table1.Width = 4800;
//这个i是单元格索引,600是要设置的列宽
table1.SetColumnWidth(i , 600);

难点三:增加行代码所写的位置

坑三:增加行位置没写对将导致结果word格式损坏无法打开

如果你以为NPOI增加行应该比较健壮,不用走中间模板,可以在后面要赋值的时候再增加

你将喜提结果word格式损坏无法打开

所以你得和增加列写在同一片位置,最后再保存为中间模板,不要先写增加列后存为中间模板,再打开中间模板写新增行

坑四:增加行写在增加列前,增加的行还多了若干列

大概长这样,是不是很幽默,猜测和新增列时干的cttbl.tblGrid.AddNewGridCol();有关,应该是新增行会自动帮你补全grid,你再加grid就多余了,所以表格就突出了一块。

增加行写在增加列的后面即可解决

总结

绕过如上坑,你就喜提了一个按照你所愿增加行和列的数据模板了

你一定很想问,既然要填入数据的也是一个中间模板,为什么不直接在中间模板里,新建一个根据动态表格数据解析出的m行n列模板,比如document.CreateTable(m, n)一步到位呢

如果你的表格很常规,ok;但是我的情况,如上图所示,一行一列有一个表格对角线,我不知道NPOI怎么弄一个对角线,我必须得在文档模板里保留这个东西,所以为了醋包了一顿饺子。

参考:

https://www.cnblogs.com/pengboke/p/17810111.html