JAVA开发一个合并单元格报表_9、docx4j实现动态表格(编程式)单元格合并

http://www.chendd.cn/information/viewInformation/other/258.a

凡是表格都会涉及到单元格合并效果,本篇文章主要是以编程式的方式给大家实现一些单元格合并的效果,包括有横向合并、纵向合并、多列(既包括横向也包含纵向)合并,在示例中我先用编程式的方式创建一个表格作为原表格,并且设置这个表格边框及背景色(待合并区域均有背景色区分),再创建一个表格用作于单元格合并,直接上截图和代码,参考如下:

1539585714273080332.png.image

待合并表格效果

1539585723741059082.png.image

合并后的表格效果

参考代码为:

package cn.chendd.docx4j.examples;

import java.io.File;

import java.math.BigInteger;

import org.docx4j.jaxb.Context;

import org.docx4j.openpackaging.packages.WordprocessingMLPackage;

import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;

import org.docx4j.wml.CTBorder;

import org.docx4j.wml.CTShd;

import org.docx4j.wml.CTVerticalJc;

import org.docx4j.wml.Jc;

import org.docx4j.wml.JcEnumeration;

import org.docx4j.wml.ObjectFactory;

import org.docx4j.wml.P;

import org.docx4j.wml.PPr;

import org.docx4j.wml.STBorder;

import org.docx4j.wml.STShd;

import org.docx4j.wml.STVerticalJc;

import org.docx4j.wml.Tbl;

import org.docx4j.wml.TblBorders;

import org.docx4j.wml.TblPr;

import org.docx4j.wml.TblWidth;

import org.docx4j.wml.Tc;

import org.docx4j.wml.TcPr;

import org.docx4j.wml.TcPrInner.HMerge;

import org.docx4j.wml.TcPrInner.TcBorders;

import org.docx4j.wml.TcPrInner.VMerge;

import org.docx4j.wml.Tr;

public class TableMergeTest {

public static void main(String[] args) throws Exception {

WordprocessingMLPackage wordPackage = WordprocessingMLPackage.createPackage();

MainDocumentPart mainDocumentPart = wordPackage.getMainDocumentPart();

ObjectFactory objectFactory = Context.getWmlObjectFactory();

mainDocumentPart.addStyledParagraphOfText("Subtitle", "创建原始Table表格");

//创建一个原始的table

Tbl dataTable = createDataTable(mainDocumentPart, objectFactory);

mainDocumentPart.addObject(dataTable);

mainDocumentPart.addStyledParagraphOfText("Subtitle", "创建合并单元格Table表格");

//创建一个表格,用于合并单元格,方便

Tbl mergeTable = createDataTable(mainDocumentPart, objectFactory);

mainDocumentPart.addObject(mergeTable);

mergeTable1(mergeTable , wordPackage);

mergeTable2(mergeTable , wordPackage);

mergeTable3(mergeTable , wordPackage);

String outPath = System.getProperty("user.dir") + "/template/out/编程式表格--单元格合并.docx";

wordPackage.save(new File(outPath));

}

//合并单元格第八九十行的,二三列,相当于是多列合并

private static void mergeTable3(Tbl mergeTable,

WordprocessingMLPackage wordPackage) {

CTVerticalJc vjc = new CTVerticalJc();

vjc.setVal(STVerticalJc.CENTER);

//REMARK:先纵向合并再横向合并,或者先横向合并再纵向合并,都是可以的,某些地方的实现好像使用到了gridSpan函数

//先纵向合并单元格第7、8、9列

Tr tr = (Tr) mergeTable.getContent().get(7);

Tc beginTd = (Tc) tr.getContent().get(1);

VMerge merge = new VMerge();

merge.setVal("restart");

beginTd.getTcPr().setVMerge(merge);

beginTd.getTcPr().setVAlign(vjc);//上下垂直居中

Tr ttt = (Tr) mergeTable.getContent().get(8);

Tc aaa = (Tc) ttt.getContent().get(1);

VMerge ab = new VMerge();

ab.setVal("continue");

aaa.getTcPr().setVMerge(ab);

aaa.getTcPr().setVAlign(vjc);//上下垂直居中

Tr tr2 = (Tr) mergeTable.getContent().get(9);

Tc bbb = (Tc) tr2.getContent().get(1);

VMerge mm = new VMerge();

mm.setVal("continue");

bbb.getTcPr().setVMerge(mm);

bbb.getTcPr().setVAlign(vjc);//上下垂直居中

//横向合并第7行

int arrV1[][] = new int[][]{

{7,1},

{7,2}

};

int arrV2[][] = new int[][]{

{8,1},

{8,2}

};

int arrV3[][] = new int[][]{

{9,1},

{9,2}

};

//横向合并第7行

for(int i=0 ; i < arrV1.length ; i++){

int ays[] = arrV1[i];

Tr beginTr = (Tr) mergeTable.getContent().get(ays[0]);

Tc td = (Tc) beginTr.getContent().get(ays[1]);

HMerge vmerge = new HMerge();

if(i == 0){

vmerge.setVal("restart");

} else {

vmerge.setVal("continue");

}

td.getTcPr().setHMerge(vmerge);

td.getTcPr().setVAlign(vjc);//上下垂直居中

}

//横向合并第8行

for(int i=0 ; i < arrV2.length ; i++){

int ays[] = arrV2[i];

Tr beginTr = (Tr) mergeTable.getContent().get(ays[0]);

Tc td = (Tc) beginTr.getContent().get(ays[1]);

HMerge vmerge = new HMerge();

if(i == 0){

vmerge.setVal("restart");

} else {

vmerge.setVal("continue");

}

td.getTcPr().setHMerge(vmerge);

td.getTcPr().setVAlign(vjc);//上下垂直居中

}

//横向合并第9行

for(int i=0 ; i < arrV3.length ; i++){

int ays[] = arrV3[i];

Tr beginTr = (Tr) mergeTable.getContent().get(ays[0]);

Tc td = (Tc) beginTr.getContent().get(ays[1]);

HMerge vmerge = new HMerge();

if(i == 0){

vmerge.setVal("restart");

} else {

vmerge.setVal("continue");

}

td.getTcPr().setHMerge(vmerge);

td.getTcPr().setVAlign(vjc);//上下垂直居中

}

}

//合并单元格第六行的,所有格子

private static void mergeTable2(Tbl mergeTable,

WordprocessingMLPackage wordPackage) {

Tr tr = (Tr) mergeTable.getContent().get(5);//第三行

Tc beginTd = (Tc) tr.getContent().get(0);

CTVerticalJc vjc = new CTVerticalJc();

vjc.setVal(STVerticalJc.CENTER);

beginTd.getTcPr().setVAlign(vjc);//上下垂直居中

HMerge beginMerge = new HMerge();

beginMerge.setVal("restart");

beginTd.getTcPr().setHMerge(beginMerge);

for(int i=1 ; i <= 3 ; i++){

Tc endTd = (Tc) tr.getContent().get(i);

HMerge endMerge = new HMerge();

endMerge.setVal("continue");

endTd.getTcPr().setHMerge(endMerge);

}

}

//合并单元格第二行与第三行的第一个格子,合并后将文本居中

private static void mergeTable1(Tbl mergeTable , WordprocessingMLPackage wordPackage) {

Jc jc = new Jc();

jc.setVal(JcEnumeration.LEFT);

mergeTable.getTblPr().setJc(jc);//设置表格居左

Tr beginTr = (Tr) mergeTable.getContent().get(2);//第三行

Tc beginTd = (Tc) beginTr.getContent().get(0);

VMerge beginMerge = new VMerge();

beginMerge.setVal("restart");

beginTd.getTcPr().setVMerge(beginMerge);

Tr endTr = (Tr) mergeTable.getContent().get(3);//第四行

Tc endTd = (Tc) endTr.getContent().get(0);

VMerge endMerge = new VMerge();

endMerge.setVal("continue");

endTd.getTcPr().setVMerge(endMerge);

CTVerticalJc vjc = new CTVerticalJc();

vjc.setVal(STVerticalJc.CENTER);

beginTd.getTcPr().setVAlign(vjc);//上下垂直居中

}

public static Tbl createDataTable(MainDocumentPart mainDocumentPart,

ObjectFactory objectFactory) {

Tbl table = objectFactory.createTbl();

//创建数据行

PPr ppr = new PPr();

Jc jc = new Jc();

jc.setVal(JcEnumeration.CENTER);

ppr.setJc(jc);//单元格文本居中使用

/*Spacing spacing = new Spacing();

spacing.setAfter(BigInteger.ZERO);//删除创建段落P后的文本间距

ppr.setSpacing(spacing);*/

for(int i= 1 ; i <= 10 ; i++){

Tr dataTr = objectFactory.createTr();

for(int j=1 ; j <= 4 ; j++){

Tc tc = objectFactory.createTc();

tc.setTcPr(new TcPr());

String text = i + "_" + j;

P p = mainDocumentPart.createParagraphOfText(text);//创建的段落P有后段文本的间距

if(i == 3 && j == 1){

text = (i - 1) + "_" + j;

CTShd shd = new CTShd();

shd.setVal(STShd.CLEAR);

shd.setColor("auto");

shd.setFill("C00000");

tc.getTcPr().setShd(shd);

p = mainDocumentPart.createParagraphOfText(text);

p.setPPr(ppr);

}

if(i == 4 && j == 1){

text = (i - 2) + "_" + j;

CTShd shd = new CTShd();

shd.setVal(STShd.CLEAR);

shd.setColor("auto");

shd.setFill("C00000");

tc.getTcPr().setShd(shd);

p = mainDocumentPart.createParagraphOfText(text);

p.setPPr(ppr);

}

if(i == 6){

text = i + "_" + i;

CTShd shd = new CTShd();

shd.setVal(STShd.CLEAR);

shd.setColor("auto");

shd.setFill("FFC000");

tc.getTcPr().setShd(shd);

p = mainDocumentPart.createParagraphOfText(text);

p.setPPr(ppr);

}

if(i >= 8 && (j == 2 || j == 3)){

text = 8 + "_" + 8;

CTShd shd = new CTShd();

shd.setVal(STShd.CLEAR);

shd.setColor("auto");

shd.setFill("00B050");

tc.getTcPr().setShd(shd);

p = mainDocumentPart.createParagraphOfText(text);

p.setPPr(ppr);

}

//设置文本居中

tc.getContent().add(p);

tc.getTcPr().setTcBorders(getTcBorders());

dataTr.getContent().add(tc);

}

table.getContent().add(dataTr);

}

table.setTblPr(new TblPr());

table.getTblPr().setTblBorders(getTblBorders());//设置表格线

table.getTblPr().setTblW(getTblWidth(8000));

return table;

}

//设置表格宽度

private static TblWidth getTblWidth(int w) {

TblWidth width = new TblWidth();

width.setW(BigInteger.valueOf(w));

width.setType(TblWidth.TYPE_DXA);

return width;

}

//表格边框

private static TblBorders getTblBorders() {

//构造边框样式

CTBorder border = new CTBorder();

border.setColor("red");

border.setSz(new BigInteger("4"));

border.setSpace(new BigInteger("0"));

border.setVal(STBorder.SINGLE);

//设置边框的上下左右边框

TblBorders borders = new TblBorders();

borders.setTop(border);

borders.setBottom(border);

borders.setLeft(border);

borders.setRight(border);

return borders;

}

//单元格边框

private static TcBorders getTcBorders() {

//构造边框样式

CTBorder border = new CTBorder();

border.setColor("blue");

border.setSz(new BigInteger("15"));

border.setSpace(new BigInteger("0"));

border.setVal(STBorder.SINGLE);

//设置边框的上下左右边框

TcBorders borders = new TcBorders();

borders.setTop(border);

borders.setBottom(border);

borders.setLeft(border);

borders.setRight(border);

return borders;

}

}

运行结果文件下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值