easypoi导出word修改样式

                                                easypoi导出word修改样式

 

          easyPoi是 POI 工具类,Excel的快速导入导出,Excel模板导出,Word模板导出,可以仅仅5行代码就可以完成Excel的导入导出,修改导出格式简单粗暴,快速有效(摘自码云https://gitee.com/lemur/easypoi

        对于简单的导出,只需要对象封装map里面,在模板上用{{}}表达式写出对象,就可以导出了,网上有很多教程,这里就不在赘述了。本文主要是讲如何通过Java代码来动态的修改样式。一般我们的word模板字段不是很多,只需要封装对象就可以了

  HashMap<String, Object> map = new HashMap<String, Object>(4);
        //单个对象
        map.put("id", "1231313");
        map.put("name", "A某某");
        map.put("age", "34");
        map.put("phone", "18787674333");
        return map;

//easypoi通用导出word
  XWPFDocument s = WordExportUtil.exportWord07("/" + templateFile, map);

 导出的模板如下,这样模板字段是什么样式的,比如加粗倾斜宋体等,导出的结果就是什么样式的,只需要调整模板的样式就可以了。

对于导出内容比较多的word,通常可以利用list进行遍历导出,这样如果修改其中某些字段的样式,那就变得比较复杂了,在网上找了很久,发现这方面的资料还是比较少的,而且都没有达到理想中的效果。

经过一天的摸索与努力,终于实现了修改所有遍历的字段的样式,这样后来者如果再遇到这类问题,就不需要花费过多的时间和精力了,也算是发扬下当代互联网人的精神吧。

       word导出要求遍历的字段全部采用仿宋,小四字体,网上很容易搜到了一种方法,经过整理下过程如下

获取对象

调用easypoi会返回一个XWPFDocument的对象,获取表table,行row,空格子cell,每一个段落paragraph,然后获取run对象就可以修改样式了。

                 //获取table
                XWPFTable sourceTable = s.getTables().get(0);

                 //获取row
                XWPFTableRow sourceRow = sourceTable.getRow(3);
            
                 //获取cell
                XWPFTableCell sourceCell = sourceRow.getCell(0);
              
                 //获取每一行
                XWPFParagraph sourcePara = sourceCell.getParagraphs().get(0);
                 //获取每一个run对象 
                XWPFRun sourceRun = sourcePara.getRuns().get(0);
                 // 设置列宽
                sourceCell .setWidth(String.valueOf(sourceRow.getCell(0).getWidth()));
                sourceCell .setWidthType(sourceRow.getCell(0).getWidthType());
                // 设置垂直对齐方式
                sourceCell .setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                 // 设置水平对齐方式
                sourcePara .setAlignment(ParagraphAlignment.CENTER);
                 //修改字体的样式大小,内容,颜色等等
                sourceRun.setFontSize(12);
                sourceRun.setBold(true);
                sourceRun.setText("舜发于畎亩之中");
                sourceRun.setCapitalized(true);
                sourceRun.setColor("BED4F1");
                sourceRun.setDoubleStrikethrough(true);
                sourceRun.setEmbossed(true);
                sourceRun.setFontFamily("仿宋", XWPFRun.FontCharRange.cs);
                sourceRun.setFontSize(12);
                sourceRun.setImprinted(true);
                sourceRun.setItalic(true);
                sourceRun.setShadow(true);
                sourceRun.setStrikeThrough(true);
             
              

代码只是修改某一个空格子的样式,如果可以,那我就循环判断修改任何一个空格子了。我以为这样就可以了,但也只是我以为,也不会花费一天之久了,其中多少次想放弃呢。

       上述代码的确可以去修改遍历list字体的大小,颜色,倾斜,加粗等。顺便说下,仿宋小四,是12号。但是不可以修改为仿宋的字体格式。接下来就是踩坑排错的过程了。首先 sourceRun.setFontFamily("仿宋");这个方法可以单个参数“宋体”,也可以两个参数 cellRun.setFontFamily("仿宋", XWPFRun.FontCharRange.eastAsia);试了下,也不行。第二个参数是个枚举类,每种类型都试了也不行。全都写上也不行。放弃之心+20。无奈,只能继续百度了。

       网上又看到一个动态修改word字体样式的内容,也是差不多再深挖四层,就不贴思维导图了,看下代码就知道了,大致代码如下

 //获取fonts对象
 CTFonts tmpFonts = sourceRun.getCTR().getRPr().getRFonts();
 //设置字体
 tmpFonts.setEastAsia("仿宋");

当然了,试了下还是不行,放弃之心+20,老规矩吧这几个有的全部设置为仿宋了

                tmpFonts.setAscii("仿宋");
                tmpFonts.setEastAsia("仿宋");
                tmpFonts.setHAnsi("仿宋");
                tmpFonts.setCs("仿宋");

还是不行,放弃之心+20,然后看到了 asciiTheme 等theme,这个是不是也要设置为仿宋呢?

<w:rFonts w:ascii="仿宋" w:hAnsi="仿宋" w:cs="仿宋" w:eastAsia="仿宋" w:asciiTheme="" w:cstheme="" w:eastAsiaTheme="" w:hAnsiTheme=""/>

试了下代码只有 tmpFonts0.isSetAsciiTheme();和 tmpFonts.unsetAsciiTheme();也没有参数,返回布尔类型,那就没办法设置了。放弃之心+10.就在偶然之间发现了一些不是遍历出来的字段的内容为

<w:rFonts w:hint="eastAsia" w:ascii="仿宋" w:hAnsi="仿宋" w:eastAsia="仿宋" w:cs="Arial"/>

竟然不一样。感觉胜利女神已经在朝我挥手了。突然想起了在名侦探柯南中,小兰推理那集,工藤提到过福尔摩斯的一句话

首先要把一切不可能的结论都排除,那其余的,不管多么离奇,难以置信,也必然是无可辩驳的事实。或许剩下的是几种解释,如果这样,那就要一一地加以证实,直到最后只剩下一种具有充分根据证明的解释。

一旦你排除了所有不可能的事实外,那么剩下的,不管多么不可思议,那就是事实的真相。

 当我们排除一系列错误以后,那么真相已经离我们很近了。既然真相已经出现,剩下的只有向真相去靠拢了。

                //真相永远只有一个(名侦探柯南)
                CTFonts tmpFonts = sourceRun.getCTR().getRPr().getRFonts();
                //真相的tmpFonts0 
                CTFonts tmpFonts0 = sourceRun0.getCTR().getRPr().getRFonts();
                String fontFamily0 = sourceRun0.getFontFamily();
                System.out.println(tmpFonts0);
                //未曾从网上看到过setHint,核心代码
                tmpFonts.setHint(tmpFonts0.getHint());
                tmpFonts.setAscii(fontFamily0);
                tmpFonts.setEastAsia(fontFamily0);
                tmpFonts.setHAnsi(fontFamily0);
                tmpFonts.setCs("Arial");
                System.out.println("~~~~~~~~~~~这是真相~~~~~~~~~~~~~~~~~");
                System.out.println(tmpFonts);
                System.out.println(tmpFonts0.isSetAsciiTheme());
                System.out.println(tmpFonts0.getAsciiTheme());
                System.out.println("~~~~~~~~~~~这是我们的结果~~~~~~~~~~~~~~~~~");
                System.out.println(tmpFonts.isSetAsciiTheme());
                System.out.println(tmpFonts.getAsciiTheme());
                //也未曾看到过类似的代码,全凭借推理
                tmpFonts.unsetAsciiTheme();
                tmpFonts.unsetEastAsiaTheme();
                tmpFonts.unsetHAnsiTheme();
                System.out.println("~~~~~~~~~~这是按照真相修改后的结果~~~~~~~~~~~~~~~~~~");
                System.out.println(tmpFonts.isSetAsciiTheme());
                System.out.println(tmpFonts.getAsciiTheme());
                sourceRun.setFontSize(sourceRun0.getFontSize()); 
   /**
     * ~~~~~~~~~~~这是真相~~~~~~~~~~~~~~~~~
     * false
     * null
     * ~~~~~~~~~~~这是我们的结果~~~~~~~~~~~~~~~~~
     * true
     * null
     * ~~~~~~~~~~这是按照真相修改后的结果~~~~~~~~~~~~~~~~~~
     * false
     * null
     */

此时要注意下,我们从其他渠道获得的easypoi的jar包可能不全,我原有的就是不全的,还是从码云上拷一份吧,这是easypoi导出word的全部

 <!-- easypoi -->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>4.2.0</version>
        </dependency>

        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.2.0</version>
        </dependency>
        <!-- Word 需要使用 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.3</version>
            <optional>true</optional>
        </dependency>

 验证遍历后的结果中的一个字段可以,那么就可以循环去修改样式了

 /**
     * 修改月报的样式
     * @param sourceTable
     * @param tmpFonts0
     * @param fontFamily0
     */
    public static void changeMonthStyle(XWPFTable sourceTable, CTFonts tmpFonts0, String fontFamily0) {
        // List  list =  (List)listMap.get("debtList");
        //获取table

        // final int size = list.size();

        //获取所有的行数
        int size = sourceTable.getRows().size();
        //从第三行开始遍历修改样式
        for (int i = 3; i < size; i++) {
            //获取每一行
            XWPFTableRow row = sourceTable.getRow(i);
            // 设置行高
            // row.setHeight(600);
            // 获取每一个空格子

            List<XWPFTableCell> cellList = row.getTableCells();
            //获取每一行空格的总个数
            final int cellSize = cellList.size();
            //进行循环遍历修改每一个空格的样式,标题行不修改样式
            for (int j = 0; j < cellSize && cellSize > 1; j++) {
                //获取每一个空格
                XWPFTableCell cell = row.getCell(j);
                // 设置列宽
                //   cell.setWidth(String.valueOf(sourceRow.getCell(j).getWidth()));
                //   cell.setWidthType(sourceRow.getCell(j).getWidthType());
                // 设置垂直对齐方式
                cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                //获取空格子里面的每一个行
                XWPFParagraph cellPara = cell.getParagraphs().get(0);
                // 设置水平对齐方式
                //  cellPara.setAlignment(ParagraphAlignment.CENTER);
                XWPFRun cellRun = cellPara.getRuns().get(0);
                System.out.println(cellRun.getText(0));
                String text = cellRun.getText(0);
                cellRun.setFontSize(12);
                //全网独一份,根据模板的样式设置总的样式
                CTFonts tmpFonts = cellRun.getCTR().getRPr().getRFonts();
                tmpFonts.setHint(tmpFonts0.getHint());
                tmpFonts.setAscii(fontFamily0);
                tmpFonts.setEastAsia(fontFamily0);
                tmpFonts.setHAnsi(fontFamily0);
                tmpFonts.setCs("Arial");
                tmpFonts.unsetAsciiTheme();
                tmpFonts.unsetEastAsiaTheme();
                tmpFonts.unsetHAnsiTheme();
                if (text.equals("资产总计") || text.equals("负债合计") ||
                        text.equals("所有者权益合计") || text.equals("负债和所有者权益总计") ||
                        text.equals("净利润") || text.equals("经营活动产生的现金流量净额") ||
                        text.equals("经营活动产生的现金流量净额") || text.equals("筹资活动产生的现金流量净额") ||
                        text.equals("现金及现金等价物净增加额") || text.equals("年末现金及现金等价物余额")
                ) {
                    //字体加粗第0列1列2列3列
                    cellRun.setBold(true);
                    row.getCell(j + 1).getParagraphs().get(0).getRuns().get(0).setBold(true);
                    row.getCell(j + 2).getParagraphs().get(0).getRuns().get(0).setBold(true);
                    row.getCell(j + 3).getParagraphs().get(0).getRuns().get(0).setBold(true);

                }

            }
        }
    }

到此,样式修改就完成了 。

有时候有些事,总是想放弃,却又一步一步走了下来。就在突然间灵光一现,答案就在眼前不远处。知识的积累同样如此,可能在很长的一段时间没有感觉到进步,可能是因为还没有到达质变的点,或在下一瞬间,就会突飞猛进,走上人生巅峰!共勉!

 参考文章如下:

EasyPOI导出Word定制版

poi导出word ,中文 字体样式 问题

码云easypoi

福尔摩斯名言

 

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值