You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

POI XWPFTable多行垂直合并导致表格异常问题排查

问题描述

我有一个4×4的XWPFTable实例sampleTable,想要将前三列实现垂直合并(每列的4行合并为一个单元格)。但运行以下代码后:

XWPFTable sampleTable=sampleDOCX.createTable(4, 4);
for(int col=0;col<3;col++){
    for(int row=0;row<4;row++){
        XWPFTableCell cell=sampleTable.getRow(row).getCell(col);
        if(row==0){
            cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
        }else{
            cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
        }
    }
}

得到的表格中前两列的行莫名被删除,且检查XML后发现,第一行的0、1号单元格并未添加<w:vMerge w:val="restart"/>标签——也就是STMerge.RESTART完全没生效,请问这是什么原因?

问题原因与解决方法

核心原因

POI创建表格时,会对前几列的单元格默认启用样式共享机制,即多个单元格复用同一个CTTcPr(单元格属性)对象。你的代码里直接调用addNewTcPr(),会覆盖原有共享的属性配置,导致第一行设置的restart被后续行的continue操作冲掉,最终前两列的合并配置失效,甚至触发单元格被删除的异常。

修正代码

操作单元格属性时,要先检查是否已有TcPr对象,优先复用而非直接新建,这样能避免破坏POI的样式共享逻辑:

XWPFTable sampleTable = sampleDOCX.createTable(4, 4);
for(int col = 0; col < 3; col++){
    for(int row = 0; row < 4; row++){
        XWPFTableCell cell = sampleTable.getRow(row).getCell(col);
        // 先获取现有TcPr,不存在再新建
        CTTcPr tcPr = cell.getCTTc().getTcPr();
        if (tcPr == null) {
            tcPr = cell.getCTTc().addNewTcPr();
        }
        // 先获取现有VMerge,不存在再新建
        CTVMerge vMerge = tcPr.getVMerge();
        if (vMerge == null) {
            vMerge = tcPr.addNewVMerge();
        }
        // 设置合并类型
        if(row == 0){
            vMerge.setVal(STMerge.RESTART);
        }else{
            vMerge.setVal(STMerge.CONTINUE);
        }
    }
}

内容的提问来源于stack exchange,提问作者Adnan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:21:15