http://www.chendd.cn/information/viewInformation/other/258.a
凡是表格都会涉及到单元格合并效果,本篇文章主要是以编程式的方式给大家实现一些单元格合并的效果,包括有横向合并、纵向合并、多列(既包括横向也包含纵向)合并,在示例中我先用编程式的方式创建一个表格作为原表格,并且设置这个表格边框及背景色(待合并区域均有背景色区分),再创建一个表格用作于单元格合并,直接上截图和代码,参考如下:
待合并表格效果
合并后的表格效果
参考代码为:
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;
}
}
运行结果文件下载