使用Apache Poi导出Word总结

我使用的poi版本是4.1.2。

下面开始使用之旅。

首先就是生成word的方法

 /**
     * 我们使用try with source方式即try(){}
     * 可以将需要关闭的资源写在try后面的括号中,会自动关闭需要关闭的资源,避免资源得不到关闭
     *
     * 我们使用XWPFDocument可以用来生成docx后缀的word
     * 使用输出流指定输出文件名称以及输出文件地址
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        try (XWPFDocument doc = new XWPFDocument(); OutputStream fos = new FileOutputStream("d:\\test\\wordTest.docx")) {

            //将缓冲区的内容刷一下
            fos.flush();
            //将输出流中的内容写入word中
            doc.write(fos);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

顺便提一下,如果想生成的word在网页上导出下载,需要配置一些东西并将使用该配置

具体如下:

   public static OutputStream getWordOutputStream(HttpServletResponse response, String fileName) throws IOException {
        response.setContentType("application/x-msdownload;");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        //  客户端不缓存
        response.addHeader("Pragma", "no-cache");
        response.addHeader("Cache-Control", "no-cache");
        return response.getOutputStream();
    }

下面运行一下main方法,看看效果如何。

 执行main方法前,文件夹里面没有内容

执行main方法后,文件夹里面多出了文件

 此时wordTest.docx里面还是没有内容的,我们现在开始对doc文件进行操作。

 首先是对word内容进行操作,生成第一行标题内容

 public static void main(String[] args) throws IOException {
        try (XWPFDocument doc = new XWPFDocument(); OutputStream fos = new FileOutputStream("d:\\test\\wordTest.docx")) {
            //创建段落
            XWPFParagraph titleParagraph = doc.createParagraph();
            //设置段落居中
            titleParagraph.setAlignment(ParagraphAlignment.CENTER);
            //设置行距为传进来的size
            setSingleLineSpacing(titleParagraph, 28);
            //设置段落大纲等级
            setOutLineLevel(titleParagraph, 0, "Heading0");
            //获取段落文本对象
            XWPFRun titleParagraphRun = titleParagraph.createRun();
            //设置段落文本的文本内容
            titleParagraphRun.setText("Hello Word!\tI`m coming!");
            //设置段落文本的字体大小
            titleParagraphRun.setFontSize(22);
            //设置段落文本的字体
            titleParagraphRun.setFontFamily("方正小标宋_GBK");


            //将缓冲区的内容刷一下
            fos.flush();
            //将输出流中的内容写入word中
            doc.write(fos);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void setOutLineLevel(XWPFParagraph paragraph, int level, String styleId) {
        //获取设置样式对象
        CTStyle ctStyle = CTStyle.Factory.newInstance();
        //设置样式等级名称
        ctStyle.setStyleId(styleId);
        CTP ctp = paragraph.getCTP();
        CTPPr ctpPr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
        CTDecimalNumber ctDecimalNumber = ctpPr.isSetOutlineLvl() ? ctpPr.getOutlineLvl() : ctpPr.addNewOutlineLvl();
        //设置大纲等级,不设置默认为正文文本,设置的话0对应大纲等级一级
        ctDecimalNumber.setVal(BigInteger.valueOf(level));
        ctpPr.setOutlineLvl(ctDecimalNumber);
        ctStyle.setPPr(ctpPr);
        XWPFStyle style = new XWPFStyle(ctStyle);
        //设置应用于段落
        style.setType(STStyleType.PARAGRAPH);
    }


    private static CTSpacing setSingleLineSpacing(XWPFParagraph paragraph, int size) {
        CTP ctp = paragraph.getCTP();
        CTPPr ctpPr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
        CTSpacing ctSpacing = ctpPr.isSetSpacing() ? ctpPr.getSpacing() : ctpPr.addNewSpacing();
        //设置文本缩进,文本之前缩进0
        ctSpacing.setBefore(BigInteger.ZERO);
        //设置文本缩进,文本之后缩进0
        ctSpacing.setAfter(BigInteger.ZERO);
        //设置行间距规则为精确值
        ctSpacing.setLineRule(STLineSpacingRule.EXACT);
        //设置行间距值,单位磅
        ctSpacing.setLine(BigInteger.valueOf(size * 20));
        return ctSpacing;
    }

下面,我们来看效果如何。

 我们可以看到文本确实居中了,字体大小22号就是对应二号字体,字体就是我们指定的字体。

 我们可以看到大纲级别变成了1级,并且间距那一栏是我们想要的结果。

在添加一些内容

            XWPFParagraph firstParagraph = doc.createParagraph();
            //设置大纲等级为2级
            setOutLineLevel(firstParagraph, 1,"Heading1");
            XWPFRun firstParagraphRun = firstParagraph.createRun();
            //设置首行缩进
            firstParagraph.setIndentationFirstLine(420);
            setSingleLineSpacing(firstParagraph, 29);
            firstParagraphRun.setText("1.测试word操作1");
            firstParagraphRun.setFontSize(16);
            firstParagraphRun.setFontFamily("方正楷体_GBK");
            //设置加粗
            firstParagraphRun.setBold(true);

 默认的对齐方式就是两端对齐,字体大小16号就是对应三号字体,字体就是我们指定的字体,并且wps自动识别到了我们的大纲级别。

我们可以看到大纲级别变成了2级,并且首行缩进确实设置成功了,但是首行缩进有一个计算的过程,首先是将我们输入的值除以20计算出一个值,然后转化为度量值。具体请看:Word字体大小对照换算表(字号、磅、英寸、像素)_word字体对照表_QAQ_King的博客-CSDN博客

继续进行操作

            XWPFParagraph textParagraph = doc.createParagraph();
            //设置对齐方式为两端对齐
            textParagraph.setAlignment(ParagraphAlignment.BOTH);
            textParagraph.setIndentationFirstLine(600);
            CTSpacing textCTSpacing = setSingleLineSpacing(textParagraph, 28);
            //设置段前间距
            textCTSpacing.setBeforeLines(BigInteger.valueOf(19));
            XWPFRun textParagraphRun = textParagraph.createRun();
            textParagraphRun.setText("2.测试word操作2");
            textParagraphRun.setFontFamily("方正仿宋_GBK");
            textParagraphRun.setFontSize(16);
            //设置斜体
            textParagraphRun.setItalic(true);

 我们可以看到没有设置大纲等级,wps是识别他为正文文本的。

 大纲级别默认为正文文本,段前间距也是我们设置的值。

操作一下

            XWPFParagraph allParagraph = doc.createParagraph();
            allParagraph.setAlignment(ParagraphAlignment.LEFT);
            allParagraph.setIndentationFirstLine(600);
            setSingleLineSpacing(allParagraph, 28);
            setOutLineLevel(allParagraph,2,"Heading2");
            XWPFRun allParagraphRun = allParagraph.createRun();
            allParagraphRun.setText("3.测试word操作3");
            allParagraphRun.setFontSize(16);
            allParagraphRun.setFontFamily("黑体");

 

 下面我们对word里面的表格进行操作

            //创建表
            XWPFTable table = creatTable(doc);
            //表格第一行
            XWPFTableRow infoTableRowOne = table.getRow(0);
            //设置表格高度
            infoTableRowOne.setHeight(400);
            //获取单元格
            XWPFTableCell oneCell1 = infoTableRowOne.getCell(0);
            //设置表格中数据居中
            setTableCenter(oneCell1);
            oneCell1.setText("test");
            //获取到第一个单元格后使用此方法自动增加
            XWPFTableCell oneCell2 = infoTableRowOne.addNewTableCell();
            setTableCenter(oneCell2);
            oneCell2.setText("word");


     private static void setTableCenter(XWPFTableCell cell) {
        CTTc ctTc = cell.getCTTc();
        CTTcPr ctTcPr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr();
        CTVerticalJc ctVerticalJc = ctTcPr.isSetVAlign() ? ctTcPr.getVAlign() : ctTcPr.addNewVAlign();
        //设置单元格垂直对齐方式为居中
        ctVerticalJc.setVal(STVerticalJc.CENTER);
        CTP ctp = ctTc.getPList().get(0);
        CTPPr ctpPr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr();
        CTJc ctJc = ctpPr.isSetJc() ? ctpPr.getJc() : ctpPr.addNewJc();
        //设置水平居中
        ctJc.setVal(STJc.CENTER);
    }

    private static XWPFTable creatTable(XWPFDocument doc) {
        //基本信息表格
        XWPFTable table = doc.createTable();
        //设置表格居中
        table.setTableAlignment(TableRowAlign.CENTER);
        //增加表格边框
        CTTblBorders borders = table.getCTTbl().getTblPr().addNewTblBorders();
        setBorder(borders);
        //列宽自动分割
        CTTblWidth infoTableWidth = table.getCTTbl().addNewTblPr().addNewTblW();
        infoTableWidth.setType(STTblWidth.DXA);
        //设置表的列宽
        infoTableWidth.setW(BigInteger.valueOf(9072));
        return table;
    }

    private static void setBorder(CTTblBorders borders) {
        CTBorder hBorder = borders.addNewInsideH();
        hBorder.setVal(STBorder.SINGLE);  // 线条类型
        hBorder.setSz(BigInteger.ONE); // 线条大小
        hBorder.setColor("000000"); // 设置颜色

        CTBorder vBorder = borders.addNewInsideV();
        vBorder.setVal(STBorder.SINGLE);
        vBorder.setSz(BigInteger.ONE);
        vBorder.setColor("000000");

        CTBorder lBorder = borders.addNewLeft();
        lBorder.setVal(STBorder.SINGLE);
        lBorder.setSz(BigInteger.ONE);
        lBorder.setColor("000000");

        CTBorder rBorder = borders.addNewRight();
        rBorder.setVal(STBorder.SINGLE);
        rBorder.setSz(BigInteger.ONE);
        rBorder.setColor("000000");

        CTBorder tBorder = borders.addNewTop();
        tBorder.setVal(STBorder.SINGLE);
        tBorder.setSz(BigInteger.ONE);
        tBorder.setColor("000000");

        CTBorder bBorder = borders.addNewBottom();
        bBorder.setVal(STBorder.SINGLE);
        bBorder.setSz(BigInteger.ONE);
        bBorder.setColor("000000");
    }

看看效果如何:

 

 循环添加数据试试

            //循环添加数据
            for (int i = 0; i < 5; i++) {
                XWPFTableRow row = table.createRow();
                row.setHeight(400);
                XWPFTableCell cell1 = row.getCell(0);
                cell1.setText("a" + i);
                setTableCenter(cell1);
                XWPFTableCell cell2 = row.getCell(1);
                cell2.setText("b" + i);
                setTableCenter(cell2);
            }

 看看效果

 也是成功的出来了结果。

以上就是我对操作word的一个总结,如果大家还有什么其他的操作欢迎留言,我们一起探讨!

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值