Java 使用POI生成word

2022-07-27,,,

POI生成word

项目中,经常需要导出word文件,而有些项目导出时没有模板,需要自动生成文件并导出。

在此背景下,本人调研了两个技术来自动生成:spiredoc和poi

spiredoc的具体使用在我之前的一篇博客里具体讲到了,今天主要分享下poi的使用方法,主要有:文档的生成,主要样式的设置,表格的生成(包括单元格的合并等),页眉和页脚的设置等等

话不多说,直接上代码:

pom引入依赖:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>3.15</version>
</dependency>

java代码如下:

package com.glodon.doc;

import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.File;
import java.io.FileOutputStream;
import java.math.BigInteger;

/**
 * @Author: yinjw-b
 * @Date: 2020/11/25 16:23
 * @Description:
 */
public class ExportWordTest {
    public static void main(String[] args) throws Exception {
        //生成文档
        XWPFDocument document = new XWPFDocument();

        //文件输出流
        FileOutputStream out = new FileOutputStream(new File("D:\\信用文档.docx"));

        //添加标题
        createDocumentTitle(document);

        // 信息汇总
        createSecondTitle(document, "信息汇总");
        createSummaryCredit(document);

        // 基本信息
        createSecondTitle(document, "基本信息");
        createBaseInfo(document);


        CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
        XWPFHeaderFooterPolicy policy = new XWPFHeaderFooterPolicy(document, sectPr);

        //添加页眉
        CTP ctpHeader = CTP.Factory.newInstance();
        CTR ctrHeader = ctpHeader.addNewR();
        CTText ctHeader = ctrHeader.addNewT();
        String headerText = "广联达西安科技有限公司";
        ctHeader.setStringValue(headerText);
        XWPFParagraph headerParagraph = new XWPFParagraph(ctpHeader, document);
        //设置为右对齐
        headerParagraph.setAlignment(ParagraphAlignment.RIGHT);
        XWPFParagraph[] parsHeader = new XWPFParagraph[1];
        parsHeader[0] = headerParagraph;
        policy.createHeader(XWPFHeaderFooterPolicy.DEFAULT, parsHeader);


        //添加页脚
        CTP ctpFooter = CTP.Factory.newInstance();
        CTR ctrFooter = ctpFooter.addNewR();
        CTText ctFooter = ctrFooter.addNewT();
        String footerText = "GLODON";
        ctFooter.setStringValue(footerText);
        XWPFParagraph footerParagraph = new XWPFParagraph(ctpFooter, document);
        headerParagraph.setAlignment(ParagraphAlignment.CENTER);
        XWPFParagraph[] parsFooter = new XWPFParagraph[1];
        parsFooter[0] = footerParagraph;
        policy.createFooter(XWPFHeaderFooterPolicy.DEFAULT, parsFooter);


        document.write(out);
        out.close();
        System.out.println("create_table document written success.");
    }

    // word跨列合并单元格
    public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
        for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
            if (cellIndex == fromCell) {
                // The first merged cell is set with RESTART merge value
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                // Cells which join (merge) the first one, are set with CONTINUE
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    // word跨行并单元格
    public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            if (rowIndex == fromRow) {
                // The first merged cell is set with RESTART merge value
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                // Cells which join (merge) the first one, are set with CONTINUE
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    // 单元格字体设置
    private static void setParagraph(XWPFTableCell cell, String cellText) {
        CTP ctp = CTP.Factory.newInstance();
        XWPFParagraph p = new XWPFParagraph(ctp, cell);
        p.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun run = p.createRun();
        run.setText(cellText);
        run.setFontFamily("宋体");
        run.setFontSize(11);
        cell.setParagraph(p);
    }

    // 表格标题单元格设置
    private static void setTableTitle(XWPFTableCell cell, String cellText) {
        CTP ctp = CTP.Factory.newInstance();
        XWPFParagraph p = new XWPFParagraph(ctp, cell);
        p.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun run = p.createRun();
        run.setText(cellText);
        run.setFontFamily("宋体");
        run.setFontSize(11);
        cell.setParagraph(p);
        cell.setColor("BFBFBF");
    }

    /**
     * 添加标题
     * @param document
     */
    private static void createDocumentTitle(XWPFDocument document) {
        //添加标题
        XWPFParagraph titleParagraph = document.createParagraph();
        //设置段落居中
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);

        XWPFRun titleParagraphRun = titleParagraph.createRun();
        titleParagraphRun.setText("个人信用评价记录");
        titleParagraphRun.setFontFamily("宋体");
        titleParagraphRun.setFontSize(22);
        titleParagraphRun.setBold(true);
    }

    /**
     * 创建二级标题
     * @param document
     */
    private static void createSecondTitle(XWPFDocument document, String text){
        XWPFParagraph paragraph1 = document.createParagraph();
        paragraph1.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun run1 = paragraph1.createRun();
        run1.addBreak();
        run1.setText(text);
        run1.addBreak();
        run1.setFontFamily("黑体");
        run1.setFontSize(16);
        run1.setBold(true);
    }

    /**
     * 信息汇总
     * @param document
     */
    private static void createSummaryCredit(XWPFDocument document){
        XWPFParagraph paragraph2 = document.createParagraph();
        paragraph2.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun run2 = paragraph2.createRun();
        run2.setText("个人姓名:" + "广联达");
        run2.addBreak();
        run2.addBreak();
        run2.setText("申请时间:" + "2020-11-10 10:12:27");
        run2.addBreak();
        run2.addBreak();
        run2.setText("生效时间:" + "2020-11-10 13:49:25");
        run2.addBreak();
        run2.addBreak();
        run2.setText("失效时间:" + "2021-11-09 13:49:25");
        run2.addBreak();
        run2.addBreak();
        run2.setText("总分:" + "86");
        run2.addBreak();
        run2.addBreak();
        run2.setText("等级:" + "AAAA");
        run2.addBreak();
        run2.addBreak();
        run2.setText("基本信息得分:" + "70");
        run2.addBreak();
        run2.addBreak();
        run2.setText("良好行为得分:" + "18");
        run2.addBreak();
        run2.addBreak();
        run2.setText("不良行为减分:" + "-2");
        run2.addBreak();
        run2.addBreak();
        run2.setFontFamily("宋体");
        run2.setFontSize(11);
    }

    /**
     * 基本信息
     * @param document
     */
    private static void createBaseInfo(XWPFDocument document) {
        // 画表格
        for (int i = 0; i < 3; i++) {

            XWPFParagraph paragraph4 = document.createParagraph();
            paragraph4.setAlignment(ParagraphAlignment.LEFT);
            XWPFRun run4 = paragraph4.createRun();
            run4.addBreak();
            run4.setText("测试");
            run4.addBreak();
            run4.setText("-------------------------------------------------");
            run4.addBreak();
            run4.setFontFamily("宋体");
            run4.setFontSize(11);

            //工作经历表格
            XWPFTable ComTable = document.createTable();

            //列宽自动分割
            CTTblWidth comTableWidth = ComTable.getCTTbl().addNewTblPr().addNewTblW();
            comTableWidth.setType(STTblWidth.DXA);
            comTableWidth.setW(BigInteger.valueOf(9072));

            //表格第一个标题
            XWPFTableRow comTableRowOne = ComTable.getRow(0);
            setTableTitle(comTableRowOne.getCell(0), "评分");
            comTableRowOne.addNewTableCell().setText("");

            for (int i1 = 0; i1 < 3; i1++) {
                XWPFTableRow comTableRowTwo = ComTable.createRow();
                setParagraph(comTableRowTwo.getCell(0), "评分内容" + i1);
                setParagraph(comTableRowTwo.getCell(1), "这是评分内容,评分内容" + i1);
            }

            //表格第二个标题
            XWPFTableRow comTableRowThree = ComTable.createRow();
            setTableTitle(comTableRowThree.getCell(0), "评分信息");
            for (int i1 = 0; i1 < 2; i1++) {
                XWPFTableRow comTableRowTwo = ComTable.createRow();
                setParagraph(comTableRowTwo.getCell(0), "评分信息" + i1);
                setParagraph(comTableRowTwo.getCell(1), "这是提交的信息" + i1);
            }

            mergeCellsHorizontal(ComTable, 0, 0, 1);
            mergeCellsHorizontal(ComTable, 4, 0, 1);
        }
    }
}

生成文档效果如下:

效果好像还不错,这些都是poi的常用操作,适用于大部分使用场景,当然其他操作可以参考poi官方文档

本文地址:https://blog.csdn.net/qq_38901340/article/details/110224968

《Java 使用POI生成word.doc》

下载本文的Word格式文档,以方便收藏与打印。