我有一个大小为4x4的XWPFTable sampleTable,我希望前三列合并如下

。但是,在这里运行代码之后:
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);
}
}
}我得到的桌子是

。前两列正在以某种方式删除它们的行。
编辑:在仔细检查时,<w:vMerge w:val="restart"/>值没有添加到XML的单元格0和1中,这意味着STMerge.RESTART没有添加到它们中。为什么标签没有写在上面?
发布于 2022-08-29 17:55:39
您的代码有以下缺点:使用cell.getCTTc().addNewTcPr(),代码总是添加新的TcPr。但是,如果表单元格已经具有表单元格属性怎么办?表单元格必须只有一个TcPr。
我在How to colspan a table in word with APACHE POI中的代码考虑了这一点。mergeCellVertically(XWPFTable table, int col, int fromRow, int toRow)方法总是首先尝试获取TcPr,并且只有在得到null之后才会添加一个新的TcPr。
但LibreOffice和OpenOffice都是自己的东西。正如我在链接答案中的代码所告诉的那样,LibreOffice和OpenOffice需要表格网格才能完全接受这些表。网格的目的是定义列宽比。因此,如果表的宽度设置为"100%",那么正确的网格宽度并不重要。只有比率才重要。
再次完成示例:
import java.io.FileOutputStream;
import java.math.BigInteger;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
public class CreateWordTableMergeTest {
static void mergeCellVertically(XWPFTable table, int col, int fromRow, int toRow) {
for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
CTVMerge vmerge = CTVMerge.Factory.newInstance();
if(rowIndex == fromRow){
// The first merged cell is set with RESTART merge value
vmerge.setVal(STMerge.RESTART);
} else {
// Cells which join (merge) the first one, are set with CONTINUE
vmerge.setVal(STMerge.CONTINUE);
// and the content should be removed
for (int i = cell.getParagraphs().size(); i > 0; i--) {
cell.removeParagraph(0);
}
cell.addParagraph();
}
// Try getting the TcPr. Not simply setting an new one every time.
CTTcPr tcPr = cell.getCTTc().getTcPr();
if (tcPr == null) tcPr = cell.getCTTc().addNewTcPr();
tcPr.setVMerge(vmerge);
}
}
public static void main(String[] args) throws Exception {
XWPFDocument document= new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run=paragraph.createRun();
run.setText("The table:");
//create table
XWPFTable table = document.createTable(4,4);
table.setWidth("100%");
//create CTTblGrid for this table with widths of the 4 columns.
//necessary for Libreoffice/Openoffice to accept the column widths.
//values are in unit twentieths of a point (1/1440 of an inch)
//first column = 1 inches width
table.getCTTbl().addNewTblGrid().addNewGridCol().setW(BigInteger.valueOf(1*1440));
//other columns (3 in this case) also each 1 inches width
for (int col = 1 ; col < 4; col++) {
table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1*1440));
}
//using the merge methods
mergeCellVertically(table, 0, 0, 3);
mergeCellVertically(table, 1, 0, 3);
mergeCellVertically(table, 2, 0, 3);
paragraph = document.createParagraph();
FileOutputStream out = new FileOutputStream("./create_table.docx");
document.write(out);
out.close();
document.close();
}
}也应该在LibreOffice中领导o表:

https://stackoverflow.com/questions/73529637
复制相似问题