JAVA 导出 word

发布于:2025-04-12 ⋅ 阅读:(44) ⋅ 点赞:(0)

1、模板方式导出

1.1、引入 maven 依赖

<dependency>
    <groupId>com.deepoove</groupId>
    <artifactId>poi-tl</artifactId>
    <version>1.12.2</version>
</dependency>

1.2、导出文档代码

public static void main(String[] args) {

    Map<String, Object> dataMap = new HashMap<>(16);
    dataMap.put("title", "标题内容");
    String pic1 = "C:\\Users\\HARRIS\\Desktop\\打工人.jpg";
    dataMap.put("pic1", pic1);
    dataMap.put("productCategory", Texts.of("超链接").link("http://www.baidu.com.cn").create());
    dataMap.put("attachRealName", Texts.of("锚点文本").anchor("custNo").create());

    List<Student> students = new ArrayList<>(10);
    students.add(new Student("张三", 18, 23.5, "111"));
    students.add(new Student("李四", 18, 23.5, "111"));
    students.add(new Student("王五", 24, 23.5, "111"));
    students.add(new Student("马六", 24, 23.5, "111"));

    List<String[]> dataList = new ArrayList<>();
    for (Student item : students) {
        dataList.add(new String[]{item.getName(), String.valueOf(item.getAge()), String.valueOf(item.getScore()),
                item.getPrice()});
    }
    // 创建一个列表来存储行数据
    RowRenderData commonTitle = Rows.of("姓名", "年龄","分数", "price").textColor("FFFFFF").bgColor("4472C4").center().create();
    List<RowRenderData> rows = new ArrayList<>();
    // 添加表头
    rows.add(commonTitle);
    // 遍历数据集合,创建 RowRenderData 对象并添加到列表中
    for (String[] data : dataList) {
        RowRenderData row = Rows.of(data).textFontFamily("仿宋_GB2312").textFontSize(9).horizontalCenter().center().create();
        rows.add(row);
    }
    TableRenderData table = Tables.create(rows.toArray(new RowRenderData[0]));
    RowRenderData totalRow = Rows.of("合计", "", "", "80%").horizontalCenter().center().create();
    table.addRow(totalRow);

    MergeCellRule.MergeCellRuleBuilder builder = MergeCellRule.builder();
    int[] indexArr = new int[]{1};
    for (int i : indexArr) {
        for (int j = 0; j < dataList.size() / 2; j++) {
            // 纵向合并单元格
            builder.map(MergeCellRule.Grid.of(j * 2 + 1, i), MergeCellRule.Grid.of(j * 2 + 2, i));
        }
    }

    // 横向合并单元格  MergeCellRule.Grid.of(x轴下标,y轴下标)
    builder.map(MergeCellRule.Grid.of(table.getRows().size() - 1, 0), MergeCellRule.Grid.of(table.getRows().size() - 1, 2));
    MergeCellRule rule = builder.build();
    table.setMergeRule(rule);
    dataMap.put("table1", table);

    try {
        //模板路径
        String filePath =  "C:\\Users\\HARRIS\\Desktop\\testTemplate.docx";
        String url = "C:\\Users\\HARRIS\\Desktop\\out.docx";
        if (!new File(url).getParentFile().exists()) {
            boolean mkdir = new File(url).getParentFile().mkdirs();
            if (mkdir) {
                System.out.printf("创建%s目录%n", new File(url).getParentFile());
            }
        }
        //解析模板
        XWPFTemplate template = XWPFTemplate.compile(filePath);
        //渲染数据
        template.render(dataMap);
        //以文件形式输出
        template.writeAndClose(Files.newOutputStream(Paths.get(url)));
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

}

1.3 导出模板

在这里插入图片描述

1.4 导出结果

在这里插入图片描述

参考文档:
poi-tl 文档
poi-tl gitcode

2.1 poi 代码导出

2.1、maven 依赖

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.3</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version>
</dependency>

2.2、Java 生成 word 文档代码

try {

    // 创建一个文档
    XWPFDocument document = new XWPFDocument();

    // 标题
    XWPFParagraph title = document.createParagraph();
    title.setAlignment(ParagraphAlignment.CENTER);
    title.setStyle("Heading1");
    XWPFRun titleRun = title.createRun();
    titleRun.setFontFamily("方正小标宋简体");
    titleRun.setBold(true);
    titleRun.setFontSize(24);
    titleRun.setText("标题");
    titleRun.setColor("FF0000");

    // 二级标题
    XWPFParagraph subtitle = document.createParagraph();
    subtitle.setAlignment(ParagraphAlignment.CENTER);
    XWPFRun subtitleRun = subtitle.createRun();
    titleRun.setFontFamily("黑体");
    subtitleRun.setText("2025年");
    subtitleRun.setFontSize(16);

    // 单位
    XWPFParagraph institution = document.createParagraph();
    String institutionDate = LocalDateTime.now().getYear() + "年" + LocalDateTime.now().getMonthValue() + "月" + LocalDateTime.now().getDayOfMonth() + "日";
    String institutionText = "{institutionDate}XXXXXXX";
    institutionText = institutionText.replace("{institutionDate}", institutionDate);
    // 设置段落边框(仅底部边框)
    institution.setAlignment(ParagraphAlignment.CENTER);
    XWPFRun institutionRun = institution.createRun();
    institutionRun.setFontFamily("黑体");
    institutionRun.setFontSize(14);
    institutionRun.setText(institutionText);

    institution.setBorderBottom(Borders.SINGLE); // 单线样式
    // 关键代码:通过OpenXML设置边框
    CTPPr ppr = institution.getCTP().isSetPPr() ? institution.getCTP().getPPr() : institution.getCTP().addNewPPr();
    CTBorder border = ppr.isSetPBdr() ?
            ppr.getPBdr().getBottom() :
            ppr.addNewPBdr().addNewBottom();

    border.setVal(STBorder.SINGLE);
    border.setColor("FF0000");
    border.setSz(BigInteger.valueOf(24)); // 1.5磅粗
    institution.setSpacingAfter(50); // 增加段后间距

    // 内容
    generateContent(document, ParagraphAlignment.LEFT, false,
            "content",
            TEXT_COLOR, 16, "仿宋_GB2312", true, false);

    // 创建页脚策略
    XWPFFooter footer = document.createFooter(HeaderFooterType.FIRST);
    //在首页页脚中添加内容
    addFooterContent(footer, "footer", "000000");
    addFooterContent(footer, "footer");

    // 设置文档属性
    CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
    CTDocGrid grid = sectPr.addNewDocGrid();
    grid.setType(STDocGrid.LINES);
    // 设置首页不同
    sectPr.addNewTitlePg();

    // 第一段
    generateContent(document, ParagraphAlignment.LEFT, true,
            "title", TEXT_COLOR, 16, "黑体", false, false);
    String stationMetadataQualityContent = "XXXXX";
    generateContent(document, ParagraphAlignment.LEFT, false, stationMetadataQualityContent,
            TEXT_COLOR, 16, "仿宋_GB2312", true, false);

    // 第二段
    generateContent(document, ParagraphAlignment.LEFT, true,
            "title", TEXT_COLOR, 16, "黑体", false, false);

    generateContent(document, ParagraphAlignment.LEFT, false,
            "XXXXXX",
            TEXT_COLOR, 16, "仿宋_GB2312", true, false);

    // 图片 1
    XWPFParagraph p = document.createParagraph();
    p.setAlignment(ParagraphAlignment.CENTER);
    XWPFRun run = p.createRun();
    // 3. 添加图片
    try (FileInputStream is = new FileInputStream("../data/pic/1111.jpg")) {
        int pictureType = Document.PICTURE_TYPE_JPEG; // 图片类型
        int width = Units.toEMU(400); // 宽度(200像素)
        int height = Units.toEMU(260); // 高度(150像素)

        run.addPicture(is, pictureType, "1111.jpg", width, height);
    } catch (InvalidFormatException e) {
        throw new RuntimeException(e);
    }
    // 图底部描述
    generateContent(document, ParagraphAlignment.CENTER, false,
            "图1 ", TEXT_COLOR, 16, "仿宋_GB2312", false, false);

    generateContent(document, ParagraphAlignment.LEFT, true,
            "title", TEXT_COLOR, 16, "仿宋_GB2312", false, false);
    generateContent(document, ParagraphAlignment.LEFT, false,
            "content",
            TEXT_COLOR, 16, "仿宋_GB2312", true, false);

    // 表一
    generateContent(document, ParagraphAlignment.CENTER, false,
            "表1", TEXT_COLOR, 16, "仿宋_GB2312", false, false);

    XWPFTable table = document.createTable();
    table.setWidth("100%");

    XWPFTableRow tableHeader = table.getRow(0);
    tableHeader.getCell(0).setText("序号");
    tableHeader.addNewTableCell().setText("XXX");
    tableHeader.addNewTableCell().setText("XX");
    tableHeader.addNewTableCell().setText("X");
    tableHeader.addNewTableCell().setText("XXXXXX");
    setTableHeaderColor(table.getRow(0), "4f81bd");
    addTableRow(table, "1", "XXXX", "XXXX", "XXX", "47");
    addTableRow(table, "2", "XXXX", "XXXXX", "XXXX", "-");

    setAllCellsCenterAlignment(table);

    // Write the document to a file
    File file = new File("../data/test/test.docx");
    if (!file.getParentFile().exists()) {
        file.getParentFile().mkdirs();
    }
    FileOutputStream out = new FileOutputStream(file);
    document.write(out);
    out.close();
    document.close();

    System.out.println("DOCX file created successfully!");

} catch (IOException e) {
    e.printStackTrace();
}
/**
     * 按指定列的值合并单元格
     *
     * @param table       表格对象
     * @param columnIndex 合并列
     */
    private static void mergeCellsByFieldName(XWPFTable table, int columnIndex) {
        List<XWPFTableRow> rows = table.getRows();

        Map<String, MergeRange> mergeRanges = new HashMap<>();

        // 第一行是表头,不处理
        for (int rowIndex = 1; rowIndex < rows.size(); rowIndex++) {
            XWPFTableCell cell = rows.get(rowIndex).getCell(columnIndex);
            String cellValue = cell.getText();
            if (mergeRanges.containsKey(cellValue)) {
                // 继续当前合并范围
                MergeRange mergeRange = mergeRanges.get(cellValue);
                mergeRange.setEndRow(rowIndex);
            } else {
                // 开始新的合并范围
                mergeRanges.put(cellValue, new MergeRange(rowIndex, rowIndex));
            }
        }

        // 应用合并
        for (MergeRange range : mergeRanges.values()) {
            if (range.getStartRow() != range.getEndRow()) {
                mergeCellsVertically(table, columnIndex, range.getStartRow(), range.getEndRow());
            }
        }
    }

    // 纵向合并单元格
    private static void mergeCellsVertically(XWPFTable table, int col, int startRow, int endRow) {
        for (int rowIndex = startRow; rowIndex <= endRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            if (rowIndex == startRow) {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    // 横向合并单元格
    private static void mergeCellsHorizontally(XWPFTable table, int row, int startCol, int endCol) {
        for (int colIndex = startCol; colIndex <= endCol; colIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(colIndex);
            if (colIndex == startCol) {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }

    // 设置表头样式(背景色+加粗)
    private static void setTableHeaderColor(XWPFTableRow headerRow, String color) {
        List<XWPFTableCell> tableCells = headerRow.getTableCells();

        for (XWPFTableCell tableCell : tableCells) {
            // 设置背景色
            setCellBackgroundColor(tableCell, color);
        }
    }

    // 设置单元格背景色
    private static void setCellBackgroundColor(XWPFTableCell cell, String rgbColor) {
        CTTc ctTc = cell.getCTTc();
        CTTcPr tcPr = ctTc.isSetTcPr() ? ctTc.getTcPr() : ctTc.addNewTcPr();

        // 创建填充色
        CTShd shd = tcPr.isSetShd() ? tcPr.getShd() : tcPr.addNewShd();
        shd.setFill(rgbColor); // 设置十六进制颜色值
        shd.setVal(STShd.CLEAR); // 必须设置为CLEAR才能显示填充色
    }

    /**
     * 生成段落
     *
     * @param document              文档
     * @param paragraphAlignment    文档位置
     * @param contentBold           文档内容是否加粗
     * @param contentText           文档内容
     * @param contentColor          文档内容颜色
     * @param contentTextSize       文档内容字体大小
     * @param contentTextFontFamily 文档内容字体
     */
    private static XWPFParagraph generateContent(XWPFDocument document, ParagraphAlignment paragraphAlignment, boolean contentBold,
                                        String contentText, String contentColor, Integer contentTextSize,
                                        String contentTextFontFamily, Boolean addTab, Boolean addBreak) {
        XWPFParagraph content = document.createParagraph();
        content.setAlignment(paragraphAlignment);
        XWPFRun contentRun = content.createRun();
        contentRun.setBold(contentBold);
        if (addTab) {
            contentRun.addTab();
        }
        contentRun.setColor(contentColor);
        contentRun.setFontSize(contentTextSize);
        contentRun.setFontFamily(contentTextFontFamily);
        contentRun.setText(contentText);
        if (addBreak) {
            contentRun.addBreak();
        }
        return content;
    }

    /**
     * 添加 footer 内容
     *
     * @param footer
     * @param text
     * @param color
     */
    private static void addFooterContent(XWPFFooter footer, String text, String color) {
        XWPFParagraph paragraph = footer.createParagraph();
        paragraph.setSpacingAfterLines(10);
        // 创建页脚段落
        paragraph.setAlignment(ParagraphAlignment.LEFT);
        // 创建页脚内容
        XWPFRun run = paragraph.createRun();
        run.setText(text);
        run.setColor(color);
        run.setFontSize(8);
        // 添加页脚横线(可选)
        addFooterLine(paragraph, 6 ,4);
    }

    /**
     * 添加 footer 线
     *
     * @param paragraph
     * @param size
     * @param space
     */
    private static void addFooterLine(XWPFParagraph paragraph, Integer size, Integer space) {
        // 通过OpenXML设置上边框作为页脚横线
        CTPPr ppr = paragraph.getCTP().isSetPPr() ?
                paragraph.getCTP().getPPr() :
                paragraph.getCTP().addNewPPr();

        CTBorder border = ppr.isSetPBdr() ?
                ppr.getPBdr().getTop() :
                ppr.addNewPBdr().addNewTop();

        border.setVal(STBorder.SINGLE);
        border.setColor("000000");  // 黑色横线
        border.setSz(BigInteger.valueOf(size));  // 0.75磅粗
        border.setSpace(BigInteger.valueOf(space));  // 与文本间距
    }

    /**
     * 表格单行数据填充
     *
     * @param table
     * @param cells
     */
    private static void addTableRow(XWPFTable table, String... cells) {
        XWPFTableRow row = table.createRow();
        for (int i = 0; i < cells.length; i++) {
            if (row.getCell(i) == null) {
                row.createCell();
            }
            row.getCell(i).setText(cells[i]);
        }
    }

    /**
     * 表格内容居中
     *
     * @param table
     */
    private static void setAllCellsCenterAlignment(XWPFTable table) {
        for (XWPFTableRow row : table.getRows()) {
            for (XWPFTableCell cell : row.getTableCells()) {
                // 垂直居中
                cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);

                // 水平居中
                for (XWPFParagraph paragraph : cell.getParagraphs()) {
                    paragraph.setAlignment(ParagraphAlignment.CENTER);

                    // 可选:设置段落中的文本格式
                    for (XWPFRun run : paragraph.getRuns()) {
                        run.setFontSize(12);
                    }
                }
            }
        }
    }

网站公告

今日签到

点亮在社区的每一天
去签到