java中使用poi生成word

项目当中需要后端生成word,当中包含表格,折线图,文字等内容,顺手写了一个工具类,分享一下,欢迎大佬批评指正

先上pom

<poi.version>4.1.2</poi.version>
<commons-collections4.version>4.4</commons-collections4.version>
<commons-codec.version>1.13</commons-codec.version>
<commons-compress.version>1.19</commons-compress.version>
<xmlbeans.version>3.1.0</xmlbeans.version>
<ooxml-schemas.version>1.4</ooxml-schemas.version>

<!-- poi相关 -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>${poi.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>${poi.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>${poi.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>${poi.version}</version>
</dependency>
<dependency>
    <groupId>org.apachemons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>${commons-collections4.version}</version>
</dependency>
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>${commons-codec.version}</version>
</dependency>
<dependency>
    <groupId>org.apachemons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>${commons-compress.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.xmlbeans</groupId>
    <artifactId>xmlbeans</artifactId>
    <version>${xmlbeans.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>ooxml-schemas</artifactId>
    <version>${ooxml-schemas.version}</version>
</dependency>

工具类

工具类当中的BussinessException是我自定义的业务错误

import iie.cas.channelcommon.exception.BussinessException;
import lombok.Data;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

/**
 * poi 相关工具类
 *
 * @author: yxc
 * @time: 2022/1/10 11:04
 **/
public class PoiUtils {

    /**
     * 图数据对象
     * 仅代表每一个数据轴
     */
    @Data
    public static class ChartValue {
        /**
         * 标题
         */
        private String title;
        /**
         * 值列表,与下面intList二选一
         */
        private List<String> strList = new ArrayList<>();
        /**
         * 值列表,与上面strList二选一
         */
        private List<Integer> intList = new ArrayList<>();

        public ChartValue(String title) {
            this.title = title;
        }

    }

    /**
     * 创建折线图
     *
     * @author yxc
     * @date 2022/1/18 9:11
     * @param document: word的document对象
     * @param title: 图标题
     * @param valueTitle: 纵坐标标题
     * @param category: 横坐标数据
     * @param values: 纵坐标数据,可以为多个
     * @return void
    **/
    public static void createWordLineChartXML(XWPFDocument document,
                                              String title,
                                              String valueTitle,
                                              ChartValue category,
                                              ChartValue... values) throws IOException, InvalidFormatException {
        // create the chart
        XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
        // 标题
        chart.setTitleText(title);
        // 标题覆盖
        chart.setTitleOverlay(false);

        // 图例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP);

        // 分类轴标(X轴),标题位置
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        bottomAxis.setTitle(category.getTitle());
        // 值(Y轴)轴,标题位置
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
        leftAxis.setTitle(valueTitle);
        // 设置x轴数据
        XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(category.getStrList().toArray(new String[]{}));
        // LINE:折线图,
        XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
        for (ChartValue value : values) {
            // 设置y轴数据
            XDDFNumericalDataSource<Integer> area = XDDFDataSourcesFactory.fromArray(value.getIntList().toArray(new Integer[]{}));
            // 图表加载数据,折线1
            XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(countries, area);
            // 折线图例标题
            series1.setTitle(value.getTitle(), null);
            // 直线
            series1.setSmooth(false);
            // 设置标记大小
            series1.setMarkerSize((short) 6);
            // 设置标记样式,星星
            // series1.setMarkerStyle(MarkerStyle.STAR);
        }
        // 绘制
        chart.plot(data);
        // 打印图表的xml
        // System.out.println(chart.getCTChart());
    }

    /**
     * 创建标题
     *
     * @author yxc
     * @date 2022/1/18 9:26
     * @param document: word的document对象
     * @param title: 标题
     * @param subTitle: 副标题
     * @return void
    **/
    public static void createTitle(XWPFDocument document, String title, String subTitle) {
        if (StringUtils.isEmpty(title)) {
            throw new BussinessException("标题不能为空");
        }
        // 创建段落
        XWPFParagraph titleParagraph = document.createParagraph();
        XWPFRun titleRun = titleParagraph.createRun();
        titleRun.setText(title);
        // 字号
        titleRun.setFontSize(20);
        // 加粗
        titleRun.setBold(true);
        // 居中
        titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        if (StringUtils.isNotEmpty(subTitle)) {
            // 处理父标题
            XWPFParagraph subTitleParagraph = document.createParagraph();
            XWPFRun subTitleRun = subTitleParagraph.createRun();
            subTitleRun.setText(subTitle);
            // 字号
            subTitleRun.setFontSize(14);
            // 加粗
            subTitleRun.setBold(true);
            // 居中
            subTitleParagraph.setAlignment(ParagraphAlignment.CENTER);
        }
    }

    /**
     * 创建段落
     *
     * @author yxc
     * @date 2022/1/18 10:14
     * @param document: word的document对象
     * @param title: 段落标题,可以为空
     * @param paragraphStr: 段落内容
     * @return void
    **/
    public static void createParagraph(XWPFDocument document, String title, String paragraphStr) {
        if (StringUtils.isEmpty(paragraphStr)) {
            throw new BussinessException("段落不能为空");
        }
        if (StringUtils.isNotEmpty(title)) {
            // 段落标题
            // 创建段落
            XWPFParagraph titleParagraph = document.createParagraph();
            XWPFRun titleRun = titleParagraph.createRun();
            titleRun.setText(title);
            // 字号
            titleRun.setFontSize(16);
            // 加粗
            titleRun.setBold(true);
            // 居中
            titleParagraph.setAlignment(ParagraphAlignment.LEFT);
        }
        // 创建段落
        XWPFParagraph paragraph = document.createParagraph();
        XWPFRun paragraphRun = paragraph.createRun();
        // 设置文字
        paragraphRun.setText(paragraphStr);
        // 字号
        paragraphRun.setFontSize(14);
        // 两端对齐
        paragraph.setAlignment(ParagraphAlignment.BOTH);
        // 首行缩进
        paragraph.setFirstLineIndent(600);
//        paragraph.setIndentFromLeft(14 * 2);
    }

    /**
     * 表格属性对象
     */
    @Data
    public static class TableValue {
        /**
         * 列数
         */
        private int colNum;
        /**
         * 行数
         */
        private int rowNum;
        /**
         * 标题
         */
        private List<String> titleList = new ArrayList<>();
        /**
         * 内容
         */
        private List<List<String>> valueList = new ArrayList<>();
        /**
         * 表格标题
         */
        private String tableTitle;

        public TableValue(int colNum, int rowNum) {
            this.colNum = colNum;
            this.rowNum = rowNum;
        }

        public TableValue(int colNum, int rowNum, String tableTitle) {
            this.colNum = colNum;
            this.rowNum = rowNum;
            this.tableTitle = tableTitle;
        }
    }

    /**
     * 创建表格
     *
     * @author 杨旭晨
     * @date 2022/1/18 17:38
     * @param document: word对应的document对象
     * @param tableValue: 表格属性对象
     * @return void
    **/
    public static void createTable(XWPFDocument document, TableValue tableValue) {
        if (StringUtils.isNotEmpty(tableValue.getTableTitle())) {
            // 创建段落
            XWPFParagraph titleParagraph = document.createParagraph();
            XWPFRun titleRun = titleParagraph.createRun();
            titleRun.setText(tableValue.tableTitle);
            // 字号
            titleRun.setFontSize(16);
            // 加粗
            titleRun.setBold(true);
            // 居中
            titleParagraph.setAlignment(ParagraphAlignment.CENTER);
        }
        XWPFTable table = document.createTable(tableValue.rowNum, tableValue.colNum);
        // 表格宽度
        table.setWidth(100);
        // 宽度类型 百分比
        table.setWidthType(TableWidthType.PCT);
        // 水平居中
        table.setTableAlignment(TableRowAlign.CENTER);
        if (tableValue.getTitleList() != null && !tableValue.getTitleList().isEmpty()) {
            // 标题行不为空,添加标题行
            XWPFTableRow titleRow = table.getRow(0);
            // 设置高度
            titleRow.setHeight(300);
            // 设置标题行
            List<String> titleList = tableValue.getTitleList();
            for (int i = 0; i < titleList.size(); i++) {
                XWPFTableCell cell = titleRow.getCell(i);
                // 以段落的形式添加文字
                XWPFParagraph cellParagraph = cell.getParagraphArray(0);
                XWPFRun cellRun = cellParagraph.createRun();
                // 文字
                cellRun.setText(titleList.get(i));
                // 居中
                cellParagraph.setAlignment(ParagraphAlignment.CENTER);
                // 字号
                cellRun.setFontSize(12);
                // 加粗
                cellRun.setBold(true);
            }
        }
        // 内容行
        List<List<String>> valueList = tableValue.getValueList();
        for (int i = 0; i < valueList.size(); i++) {
            // 排除第一行,标题行
            XWPFTableRow valueRow = table.getRow(i + 1);
            // 设置高度
            valueRow.setHeight(300);
            List<String> values = valueList.get(i);
            for (int j = 0; j < values.size(); j++) {
                XWPFTableCell cell = valueRow.getCell(j);
                // 用段落形式添加文字
                XWPFParagraph cellParagraph = cell.getParagraphArray(0);
                XWPFRun cellRun = cellParagraph.createRun();
                // 文字
                cellRun.setText(values.get(j));
                // 居中
                cellParagraph.setAlignment(ParagraphAlignment.CENTER);
                // 字号
                cellRun.setFontSize(12);
                // 不加粗
                cellRun.setBold(false);
            }
        }
        setTableHeight(table, 600, STVerticalJc.CENTER);
    }

    /**
     * 设置表格高度
     *
     * @author 杨旭晨
     * @date 2022/1/18 17:38
     * @param infoTable: 表格
     * @param heigth: 设置的高度
     * @param vertical: xxx
     * @return void
    **/
    private static void setTableHeight(XWPFTable infoTable, int heigth, STVerticalJc.Enum vertical) {
        List<XWPFTableRow> rows = infoTable.getRows();
        for(XWPFTableRow row : rows) {
            CTTrPr trPr = row.getCtRow().addNewTrPr();
            CTHeight ht = trPr.addNewTrHeight();
            ht.setVal(BigInteger.valueOf(heigth));
            List<XWPFTableCell> cells = row.getTableCells();
            for(XWPFTableCell tableCell : cells ) {
                CTTcPr cttcpr = tableCell.getCTTc().addNewTcPr();
                cttcpr.addNewVAlign().setVal(vertical);
            }
        }
    }

    /**
     * 添加下一页分隔符
     *
     * @author yxc
     * @date 2022/1/18 11:21
     * @param document: word的document对象
     * @return void
    **/
    public static void createNextPageChar(XWPFDocument document) {
        XWPFParagraph paragraph = document.createParagraph();
        paragraph.setPageBreak(true);
    }

    /**
     * 将word输出为文件,返回文件路径
     *
     * @author yxc
     * @date 2022/1/18 9:12
     * @param outFile: 输出文件
     * @param document: word的document对象
     * @return java.lang.String
    **/
    public static String writeFile(File outFile, XWPFDocument document) {
        if (outFile == null) {
            throw new BussinessException("文件为空");
        }
        if (!outFile.getParentFile().exists()) {
            // 文件夹不存在
            outFile.getParentFile().mkdirs();
        }
        try (FileOutputStream fos = new FileOutputStream(outFile)) {
            document.write(fos);
        } catch (Exception e) {
            throw new BussinessException("文件写入失败");
        }
        return outFile.getPath();
    }

}

更多推荐

java poi生成word