Java导出word

第一步:引入poi相关包

           <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>4.1.2</version>
        </dependency>

第二步:创建工具类

/**
 * @author zhangjianshan1992
 */
public class WordTool {
    public static final String TITLE_FIRST = "一、级标题";
    public static final String TITLE_SECOND = "二、级标题";
    public static final String TITLE_THIRD = "三、级标题";
    public static final String TITLE_FOURTH = "四、级标题";

    @SneakyThrows
    public static void write(XWPFDocument document, String path) {
        FileOutputStream fileOut = new FileOutputStream(path);
        document.write(fileOut);
        fileOut.close();
    }

    public static void createTitle(XWPFDocument document, String style, String text) {
        XWPFParagraph paragraph = document.createParagraph();
        paragraph.setPageBreak(false);
        paragraph.setStyle(style);
        XWPFRun run = paragraph.createRun();
        run.setFontFamily("黑体");
        run.setFontSize(22);
        run.setText(text);
    }

    /**
     * 创建文本
     *
     * @param document 文档
     * @param txt      内容
     */
    public static void createText(XWPFDocument document, String txt) {
        XWPFParagraph remark = document.createParagraph();
        remark.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun remarkRun = remark.createRun();
        remarkRun.setFontFamily("宋体");
        remarkRun.setBold(true);
        remarkRun.setFontSize(20);
        remarkRun.setText(txt);
    }

    public static void createText(XWPFDocument document, String txt, boolean bold, int fontSize, ParagraphAlignment paragraphAlignment) {
        XWPFParagraph remark = document.createParagraph();
        remark.setAlignment(paragraphAlignment);
        XWPFRun remarkRun = remark.createRun();
        remarkRun.setFontFamily("宋体");
        remarkRun.setBold(bold);
        remarkRun.setFontSize(fontSize);
        remarkRun.setText(txt);
    }

    public static void createText(XWPFDocument document, String txt, ParagraphAlignment paragraphAlignment) {
        XWPFParagraph remark = document.createParagraph();
        remark.setAlignment(paragraphAlignment);
        XWPFRun remarkRun = remark.createRun();
        remarkRun.setFontFamily("宋体");
        remarkRun.setBold(false);
        remarkRun.setFontSize(20);
        remarkRun.setText(txt);
    }

    /**
     * 创建表格
     *
     * @param document doc
     * @param rows     行数
     * @param cols     列数
     * @return table
     */
    public static XWPFTable createTable(XWPFDocument document, int rows, int cols) {
        XWPFTable table = document.createTable(rows, cols);
        table.setCellMargins(200, 200, 200, 200);
        CTTbl bl = table.getCTTbl();
        //设置表格总宽度
        CTTblPr pr = bl.getTblPr() == null ? bl.addNewTblPr() : bl.getTblPr();
        CTTblWidth tblWidth = pr.addNewTblW();
        tblWidth.setW(BigInteger.valueOf(9000));
        tblWidth.setType(STTblWidth.DXA);
        return table;
    }

    /**
     * 跨行合并
     *
     * @param table   表格
     * @param col     列
     * @param fromRow 开始行
     * @param toRow   结束行
     */
    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) {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }


    /**
     * 跨列合并单元格
     *
     * @param table    表格
     * @param row      列
     * @param fromCell 开始行
     * @param toCell   结束行
     */
    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) {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    /**
     * 插入图片
     *
     * @param document doc
     * @param path     path
     */
    @SneakyThrows
    public static void createPicture(XWPFDocument document, String path) {
        File pictureFile = FileUtil.file(path);
        if (!pictureFile.exists()) {
            return;
        }
        InputStream inputStream = new FileInputStream(pictureFile);
        XWPFParagraph paragraph = document.createParagraph();
        //居中
        paragraph.setAlignment(ParagraphAlignment.CENTER);
        paragraph.createRun().addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG, "picture", Units.toEMU(200), Units.toEMU(200));
        closeStream(inputStream);
    }

    /**
     * 关闭输入流
     *
     * @param closeAbles
     */
    public static void closeStream(Closeable... closeAbles) {
        for (Closeable c : closeAbles) {
            if (c != null) {
                try {
                    c.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public static void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) {
        CTStyle ctStyle = CTStyle.Factory.newInstance();
        ctStyle.setStyleId(strStyleId);
        CTString styleName = CTString.Factory.newInstance();
        styleName.setVal(strStyleId);
        ctStyle.setName(styleName);
        CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance();
        indentNumber.setVal(BigInteger.valueOf(headingLevel));
        // lower number > style is more prominent in the formats bar
        ctStyle.setUiPriority(indentNumber);
        CTOnOff onoffnull = CTOnOff.Factory.newInstance();
        ctStyle.setUnhideWhenUsed(onoffnull);
        // style shows up in the formats bar
        ctStyle.setQFormat(onoffnull);
        // style defines a heading of the given level
        CTPPr ppr = CTPPr.Factory.newInstance();
        ppr.setOutlineLvl(indentNumber);
        ctStyle.setPPr(ppr);
        XWPFStyle style = new XWPFStyle(ctStyle);
        // is a null op if already defined
        XWPFStyles styles = docxDocument.createStyles();
        style.setType(STStyleType.PARAGRAPH);
        styles.addStyle(style);

    }

    public static String nullToEmpty(Object obj) {
        if (Objects.isNull(obj)) {
            return StringUtils.EMPTY;
        }
        return String.valueOf(obj);
    }

/**
     * 创建饼状
     *
     * @param document     文档
     * @param xDataList    横坐标数据
     * @param yDataList    纵坐标数据
     * @param titleText    图表标题
     * @param pieTitleText 系列提示标题
     */
    @SneakyThrows
    public static void createPieChart(XWPFDocument document, List<String> xDataList,
                                      List<Integer> yDataList, String titleText,
                                      String pieTitleText) {
        //1、创建表
        XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);
        //2、图表相关设置
        //图表标题
        chart.setTitleText(titleText);
        //图例是否覆盖标题
        chart.setTitleOverlay(false);

        //3、图例设置
        XDDFChartLegend legend = chart.getOrAddLegend();
        // 图例位置:上下左右
        legend.setPosition(LegendPosition.RIGHT);

        //4、X轴(分类轴)相关设置:饼图中的图例显示
        String[] xAxisData = xDataList.toArray(new String[0]);
        // 设置分类数据
        XDDFCategoryDataSource xAxisSource = XDDFDataSourcesFactory.fromArray(xAxisData);

        //5、Y轴(值轴)相关设置:饼图中的圆形显示
        Integer[] yAxisData = yDataList.toArray(new Integer[0]);
        // 设置值数据
        XDDFNumericalDataSource<Integer> yAxisSource = XDDFDataSourcesFactory.fromArray(yAxisData);

        //6、创建饼图对象,饼状图不需要X,Y轴,只需要数据集即可
        XDDFPieChartData pieChart = (XDDFPieChartData) chart.createData(ChartTypes.PIE, null, null);
        pieChart.setVaryColors(true);
        //7、加载饼图数据集
        XDDFPieChartData.Series pieSeries = (XDDFPieChartData.Series) pieChart.addSeries(xAxisSource, yAxisSource);
        //系列提示标题
        pieSeries.setTitle(pieTitleText, null);
        pieSeries.setShowLeaderLines(true);
        //8、绘制饼图
        chart.plot(pieChart);

    }

  /**
     * 添加word中的标记数据 标记方式为 ${text}
     *
     * @param document word对象
     * @param textMap  需要替换的信息集合
     */
    public void changeParagraphText(XWPFDocument document, Map<String, String> textMap) {
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            if (checkText(text)) {
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
                    //替换模板原来位置
                    run.setText(changeValue(run.toString(), textMap), 0);
                }
            }
        }
    }

    /**
     * 替换表格中标记的数据 标记方式为 ${text}
     * 这里有个奇怪的问题 输入${}符号的时候需要把输入法切换到中文
     * ${}中间不能用数字,不能有下划线
     *
     * @param document      word对象
     * @param tableTextList 需要替换的信息集合
     */
    public void changeTableText(XWPFDocument document, List<Map<String, String>> tableTextList) {
        //获取表格对象集合
        List<XWPFTable> tables = document.getTables();
        for (int i = 0; i < tables.size(); i++) {
            Map<String, String> textMap = tableTextList.get(i);
            //只处理行数大于等于2的表格
            XWPFTable table = tables.get(i);
            if (table.getRows().size() > 1) {
                //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
                if (checkText(table.getText())) {
                    List<XWPFTableRow> rows = table.getRows();
                    //遍历表格,并替换模板
                    eachTable(rows, textMap);
                }
            }
        }
    }

    /**
     * 判断文本中时候包含$
     *
     * @param text 文本
     * @return 包含返回true, 不包含返回false
     */
    public static boolean checkText(String text) {
        boolean check = false;
        if (text.indexOf("$") != -1) {
            check = true;
        }
        return check;
    }

    /**
     * 匹配传入信息集合与模板
     *
     * @param value   模板需要替换的区域
     * @param textMap 传入信息集合
     * @return 模板需要替换区域信息集合对应值
     */
    public static String changeValue(String value, Map<String, String> textMap) {
        Set<Map.Entry<String, String>> textSets = textMap.entrySet();
        for (Map.Entry<String, String> textSet : textSets) {
            //匹配模板与替换值 格式${key}
            String key = "${" + textSet.getKey() + "}";
            if (value.indexOf(key) != -1) {
                value = textSet.getValue();
            }
        }
        //模板未匹配到区域替换为空
        if (checkText(value)) {
            value = "";
        }
        return value;
    }

    /**
     * 遍历表格,并替换模板
     *
     * @param rows    表格行对象
     * @param textMap 需要替换的信息集合
     */
    public static void eachTable(List<XWPFTableRow> rows, Map<String, String> textMap) {
        for (XWPFTableRow row : rows) {
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                //判断单元格是否需要替换
                if (checkText(cell.getText())) {
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
                            run.setText(changeValue(run.toString(), textMap), 0);
                        }
                    }
                }
            }
        }
    }

    static CellReference setTitleInDataSheet(XWPFChart chart, String title, int column) throws Exception {
        XSSFWorkbook workbook = chart.getWorkbook();
        XSSFSheet sheet = workbook.getSheetAt(0);
        XSSFRow row = sheet.getRow(0);
        if (row == null)
            row = sheet.createRow(0);
        XSSFCell cell = row.getCell(column);
        if (cell == null)
            cell = row.createCell(column);
        cell.setCellValue(title);
        return new CellReference(sheet.getSheetName(), 0, column, true, true);
    }
}

第三步:测试用例

public class WordTest {
    public static void main(String[] args) {
        XWPFDocument document = new XWPFDocument();
        WordTool.addCustomHeadingStyle(document, WordTool.TITLE_FIRST, 1);
        WordTool.addCustomHeadingStyle(document, WordTool.TITLE_SECOND, 2);
        WordTool.addCustomHeadingStyle(document, WordTool.TITLE_THIRD, 3);
        WordTool.addCustomHeadingStyle(document, WordTool.TITLE_FOURTH, 4);
        //创建标题
        XWPFParagraph paragraph = document.createParagraph();
        paragraph.setPageBreak(true);
        paragraph.setStyle("一、级标题");
        XWPFRun run = paragraph.createRun();
        run.setFontFamily("黑体");
        run.setFontSize(22);
        run.setText("一级标题");

        XWPFParagraph campParagraph = document.createParagraph();
        campParagraph.setFirstLineIndent(600);
        campParagraph.setStyle("二、级标题");
        XWPFRun campRun = campParagraph.createRun();
        campRun.setFontFamily("黑体");
        campRun.setText("二级标题");
        campRun.setFontSize(14);

        WordTool.createText(document, "\t\t223", ParagraphAlignment.LEFT);
        WordTool.createText(document, "224");
        //创建表格
        XWPFTable table = WordTool.createTable(document, 10, 2);
        int row = 0;
        //填充标题
        XWPFTableRow firstRow = table.getRow(row);
        firstRow.getCell(0).setText("专题报告名称");
        firstRow.getCell(1).setText("13");
        //插入图片
        WordTool.createPicture(document, "D://123.png");
         //插入饼状图
        WordTool.createPieChart(document, CollectionUtil.newArrayList("甲", "乙")
                , CollectionUtil.newArrayList(1, 2), "股份图", "投资比例");
        WordTool.write(document, "D://123.docx");
    }
}

第四步:样例

在这里插入图片描述

附言其他工具访问github自取

github地址

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值