简体   繁体   English

如何在Java中使用POI水平合并XWPFTable

[英]How to horizontally merge XWPFTable using POI in Java

I want to horizontally merge columns of the row in a XWPFTable. 我想在XWPFTable中水平合并行的列。 I tried the answer in this link. 我尝试了此链接中的答案。 How to merge cells (or apply colspan) using XWPFTable in POI in Java? 如何在Java POI中使用XWPFTable合并单元格(或应用colspan)? and also of this link How to merge cells horizontally using apache-poi 以及此链接的方法如何使用apache-poi水平合并单元格

It helped me to get cells merged vertically. 它帮助我使单元垂直融合。 But horizontal merge is not happening. 但是水平合并没有发生。 I am attaching the sample screenshot of what I really wanted. 我附上我真正想要的示例屏幕截图。

Excel图像

Thanks. 谢谢。

There are two methods setting horizontally merging. 有两种设置水平合并的方法。 The first is using CTHMerge which is similar to the vertically merging using CTVMerge and it does not explicitly need a table grid. 首先是使用CTHMerge这类似于垂直合并使用CTVMerge ,它并没有明确需要一个表格。 The second is using grid span properties. 第二个是使用网格跨度属性。 This method needs a table grid and the cells which are merged with the first one must be removed. 此方法需要一个表格网格,并且必须删除与第一个网格合并的单元格。

Microsoft Word supports all methods. Microsoft Word支持所有方法。

Libreoffice Writer supports CTHMerge too but a table grid must be set because of the correct rendering the table. Libreoffice Writer支持CTHMerge但是由于正确渲染了表格,因此必须设置表格网格。

WPS Writer supports only setting grid span. WPS Writer仅支持设置网格范围。

So this should be the most compatible solution: 因此,这应该是最兼容的解决方案:

import java.io.File;
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.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;

public class CreateWordTableMerge {

 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);
  }
 }

 //merging horizontally by setting grid span instead of using CTHMerge
 static void mergeCellHorizontally(XWPFTable table, int row, int fromCol, int toCol) {
  XWPFTableCell cell = table.getRow(row).getCell(fromCol);
  // Try getting the TcPr. Not simply setting an new one every time.
  CTTcPr tcPr = cell.getCTTc().getTcPr();
  if (tcPr == null) tcPr = cell.getCTTc().addNewTcPr();
  // The first merged cell has grid span property set
  if (tcPr.isSetGridSpan()) {
   tcPr.getGridSpan().setVal(BigInteger.valueOf(toCol-fromCol+1));
  } else {
   tcPr.addNewGridSpan().setVal(BigInteger.valueOf(toCol-fromCol+1));
  }
  // Cells which join (merge) the first one, must be removed
  for(int colIndex = toCol; colIndex > fromCol; colIndex--) {
   table.getRow(row).getCtRow().removeTc(colIndex);
   table.getRow(row).removeCell(colIndex);
  }
 }

 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(3,5);

  for (int row = 0; row < 3; row++) {
   for (int col = 0; col < 5; col++) {
    table.getRow(row).getCell(col).setText("row " + row + ", col " + col);
   }
  }

  //create CTTblGrid for this table with widths of the 5 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 (2 in this case) also each 1 inches width
  for (int col = 1 ; col < 5; col++) {
   table.getCTTbl().getTblGrid().addNewGridCol().setW(BigInteger.valueOf(1*1440));
  }

  //create and set column widths for all columns in all rows
  //most examples don't set the type of the CTTblWidth but this
  //is necessary for working in all office versions
  for (int col = 0; col < 5; col++) {
   CTTblWidth tblWidth = CTTblWidth.Factory.newInstance();
   tblWidth.setW(BigInteger.valueOf(1*1440));
   tblWidth.setType(STTblWidth.DXA);
   for (int row = 0; row < 3; row++) {
    CTTcPr tcPr = table.getRow(row).getCell(col).getCTTc().getTcPr();
    if (tcPr != null) {
     tcPr.setTcW(tblWidth);
    } else {
     tcPr = CTTcPr.Factory.newInstance();
     tcPr.setTcW(tblWidth);
     table.getRow(row).getCell(col).getCTTc().setTcPr(tcPr);
    }
   }
  }

  //using the merge methods
  mergeCellVertically(table, 0, 0, 1); 
  mergeCellHorizontally(table, 1, 2, 3); 
  mergeCellHorizontally(table, 2, 1, 4); 

  paragraph = document.createParagraph();

  FileOutputStream out = new FileOutputStream("create_table.docx"); 
  document.write(out);
  out.close();

  System.out.println("create_table.docx written successully");
 }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM