9、docx4j实现动态表格(编程式)单元格合并

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

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

blob.png

待合并表格效果

blob.png

合并后的表格效果

参考代码为:    

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;

       }

      

    }

运行结果文件下载

icon_txt.gif编程式表格--单元格合并.docx

转载于:https://my.oschina.net/haiyangyiba/blog/2247142

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值