gpt4 book ai didi

java - 如何使用 APACHE POI 在 Word 中对表格进行 colspan

转载 作者:行者123 更新时间:2023-12-02 06:15:37 28 4
gpt4 key购买 nike

我有一个代码,但它适用于 rowspan 表格。你能帮我把它转换成 colspan 代码吗?

private 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);
if(rowIndex == fromRow){
// The first merged cell is set with RESTART merge value
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
}else{
// Cells which join (merge) the first one, are set with CONTINUE
cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
}
}
}

最佳答案

原理是一样的只是org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge而不是org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge

但我会更仔细地处理单元格中的 TcPr 元素。您的实际代码只是每次都创建新的 TcPr 元素。如果单元格中已经有这样的元素怎么办?

例子:

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.CTHMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;

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.setVMerge(vmerge);
} else {
// only set an new TcPr if there is not one already
tcPr = CTTcPr.Factory.newInstance();
tcPr.setVMerge(vmerge);
cell.getCTTc().setTcPr(tcPr);
}
}
}

static void mergeCellHorizontally(XWPFTable table, int row, int fromCol, int toCol) {
for(int colIndex = fromCol; colIndex <= toCol; colIndex++){
XWPFTableCell cell = table.getRow(row).getCell(colIndex);
CTHMerge hmerge = CTHMerge.Factory.newInstance();
if(colIndex == fromCol){
// The first merged cell is set with RESTART merge value
hmerge.setVal(STMerge.RESTART);
} else {
// Cells which join (merge) the first one, are set with CONTINUE
hmerge.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.setHMerge(hmerge);
} else {
// only set an new TcPr if there is not one already
tcPr = CTTcPr.Factory.newInstance();
tcPr.setHMerge(hmerge);
cell.getCTTc().setTcPr(tcPr);
}
}
}

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

2018 年 3 月 11 日编辑:

有两种设置水平合并的方法。第一种是使用 CTHMerge,它类似于使用 CTVMerge 的垂直合并,它并不明确需要表格网格。第二个是使用网格跨度属性。此方法需要一个表格网格,并且必须删除与第一个合并的单元格。

Microsoft Word 支持所有方法。

Libreoffice Writer 也支持 CTHMerge 但必须设置表格网格才能正确呈现表格。

WPS Writer 只支持设置网格跨度。

所以这应该是最兼容的解决方案:

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

关于java - 如何使用 APACHE POI 在 Word 中对表格进行 colspan,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34647624/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com