POI给word中的表格table动态添加行,并保留上一行的样式

最近在处理项目中,动态生成word格式的合同,再将word转为pdf,并为pdf添加文字、图片水印。

在生成word的时候模板中有动态添加表格行,模板如下图:

下面先上结果图:

模板上的标签变量解析是自己写的。开始想着用freemark做模板解析,但是freemark生成的word文档,无法用poi转化为pdf文档,最后放弃了,只能自己着手写。

在poi的官方代码中提供了四种添加行的方法:

table.addNewRowBetween 官方没实现
table.insertNewTableRow(pos) 在pos位置新增一行,样式为默认样式,但是这个具体是啥样式不确定。
table.addRow(XWPFTableRow newRow, int pos) 在table指定的行pos处添加一行newRow,本文将用此方法
table.addRow() 在表格最后加一行。
table.createRow() 在表格最后一加行

下面开始说具体代码

1.添加依赖,由于项目中用了poi将word转pdf的一个jar(org.apache.poi.xwpf.converter.pdf),最高只支持3.15.

<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi</artifactId>
 <version>3.15</version>
</dependency>

<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>3.15</version>
</dependency>

2.由于实际代码其他业务处理逻辑很多,下面贴出核心代码块

if (fields.size() > 0)
{
    //row为模板中的行
    //table.addRow(row, i+1);//此方法可以使新增的行和模板样式一样,但是新行赋值是会将上面行的row也修改了,
    //因为row是对象,新行只是得到一个引用,调试是可以发现后面新增的row的对象id都是一样的。
    
    //开始有想过用既然是对象,那么克隆、序列化反序列化一个呗,进入XWPFTableRow一看没实现Cloneable、Serializable接口,走不通,
    //最后没招了去看row的构造函数XWPFTableRow(CTRow row, XWPFTable table),使用模板的行构造一个鑫航,那就可以保留模板行一样
    //样式了,构造完发现newRow的对象id变了,其他的样式、单元格内容仍然保留着,接下来就是替换掉单元格的内容就好了。
    CTRow ctrow = CTRow.Factory.parse(row.getCtRow().newInputStream());//重点行
    XWPFTableRow newRow = new XWPFTableRow(ctrow, table);
    for (int k = 0; k < fields.size(); k++)
    {
        XWPFTableCell cell = newRow.getTableCells().get(k);// 在新增的行上面创建cell
        //cell.setText(fields.get(k));//不能使用该方法直接加内容,这样会在原内容后面追加,并且不能保证跟原字体样式一致
        for (XWPFParagraph p : cell.getParagraphs())
        {
            for (XWPFRun r : p.getRuns())
            {
                r.setText(fields.get(k), 0);//要深入到原cell中的run替换内容才能保证样式一致
            }
        }
    }
    table.addRow(newRow, i + 1);
    i++;// 新增一行,行索引加1,此处不+1会导致下一行,覆盖刚新增的一行
}

 

Java中,Apache POI库是一个广泛用于操作Microsoft Office文档(如Word、Excel和PowerPoint)的强大工具。如果你想要使用POIWord文档中删除现有的表格新建一个6x6的表格,你可以按照以下步骤操作: 首先,你需要添加Apache POI依赖到你的项目中。如果你的项目是Maven管理的,可以在pom.xml文件中添加如下依赖: ```xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>最新版本号</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>最新版本号</version> </dependency> ``` 然后,你可以使用以下代码示例实现这个功能: ```java import org.apache.poi.xwpf.usermodel.*; public void deleteAndCreateTable(XWPFDocument document) { // 删除现有的表格 for (XWPFParagraph paragraph : document.getParagraphs()) { if (paragraph.isTableCell()) { paragraph.remove(); } } // 创建新的6x6表格 XWPFTable table = document.createTable(6, 6); // 表格有66列 table.setRowNumFirst(true); // 设置从1开始编号 // 添加样式,美化表格 XWPFStyle style = document.getStyleFactory().createStyle("Normal"); style.applyBorderBottom(style BordBottomType.DOT_DASHED, 0.5F); table.getRow(0).getCells().get(0).getCellStyleIndex(style.getIndex()); // 可能需要保存文档 saveDocument(document); } private void saveDocument(XWPFDocument document) { try { FileOutputStream out = new FileOutputStream("new_word.docx"); document.write(out); out.close(); System.out.println("表格已创建保存至新_word.docx"); } catch (IOException e) { e.printStackTrace(); } } ``` 记得替换`"new_word.docx"`为你实际想要保存的新文件名。运这段代码后,原始文档中的所有表格将被移除,一个新的6x6表格会出现在文档的开头。
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值