替换word中的excel

发布于:2025-05-21 ⋅ 阅读:(18) ⋅ 点赞:(0)
@PostMapping("/make/report/target/performance/first")
public AjaxResult makeTargetReportFirst(@RequestBody MakeReportDTO makeReportDTO) {
    Map<String, String> textReplaceMap = new HashMap<>();

    // 替换日期
    LocalDateTime nowData = LocalDateTime.now();
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
    textReplaceMap.put("${nowDate}", nowData.format(dateFormatter));

    String templatePath = uploadPklExcelPath + "template1.docx";
    String directoryPath = fileUploadDir;

    try {
        if (!Files.exists(Paths.get(directoryPath))) {
            Files.createDirectories(Paths.get(directoryPath));
        }

        try (InputStream is = new FileInputStream(templatePath);
             XWPFDocument doc = new XWPFDocument(is)) {

            // 替换普通文本占位符(段落和表格内文本)
            replaceTextPlaceholders(doc, textReplaceMap);

            List<List<String>> excelData = makeReportDTO.getExcelData();
            if (excelData == null || excelData.isEmpty()) {
                return AjaxResult.error("excelData不能为空");
            }

            // 替换表格内容,按列替换,且新增行
            replaceTableDataByColumns(doc, excelData);

            // 生成唯一文件名
            String fileName = generateUniqueFileName();
            String outPath = directoryPath + fileName;

            try (OutputStream os = new FileOutputStream(outPath)) {
                doc.write(os);
            }

            return AjaxResult.success(outPath);
        }
    } catch (FileNotFoundException e) {
        return AjaxResult.error("文件未找到:" + e.getMessage());
    } catch (Exception e) {
        e.printStackTrace();
        return AjaxResult.error("报告生成失败:" + e.getMessage());
    }
}

    private void replaceTextPlaceholders(XWPFDocument doc, Map<String, String> replaceMap) {
        // 替换段落中的占位符
        doc.getParagraphs().forEach(paragraph -> {
            paragraph.getRuns().forEach(run -> {
                String text = run.getText(0);
                if (text != null) {
                    for (Map.Entry<String, String> entry : replaceMap.entrySet()) {
                        if (text.contains(entry.getKey())) {
                            run.setText(text.replace(entry.getKey(), entry.getValue()), 0);
                        }
                    }
                }
            });
        });

        // 替换表格中的占位符
        doc.getTables().forEach(table -> {
            table.getRows().forEach(row -> {
                row.getTableCells().forEach(cell -> {
                    cell.getParagraphs().forEach(paragraph -> {
                        paragraph.getRuns().forEach(run -> {
                            String text = run.getText(0);
                            if (text != null) {
                                for (Map.Entry<String, String> entry : replaceMap.entrySet()) {
                                    if (text.contains(entry.getKey())) {
                                        run.setText(text.replace(entry.getKey(), entry.getValue()), 0);
                                    }
                                }
                            }
                        });
                    });
                });
            });
        });
    }

    private void replaceTableDataByColumns(XWPFDocument doc, List<List<String>> excelData) {
        if (doc.getTables().isEmpty()) {
            throw new IllegalArgumentException("模板中没有表格");
        }

        XWPFTable table = doc.getTables().get(0);

        // 求最大行数
        int maxRowCount = excelData.stream()
                .mapToInt(List::size)
                .max()
                .orElse(0);

        int templateRowCount = table.getNumberOfRows();

        // 不够行就新增
        for (int i = templateRowCount; i < maxRowCount; i++) {
            table.createRow();
        }

        for (int col = 0; col < excelData.size(); col++) {
            List<String> colData = excelData.get(col);

            for (int row = 0; row < maxRowCount; row++) {
                XWPFTableRow tableRow = table.getRow(row);

                // 设置固定高度为 5mm(约 284 Twips)
                tableRow.setHeight(284);
                tableRow.setHeightRule(TableRowHeightRule.EXACT);

                // 确保当前行有对应列单元格
                while (tableRow.getTableCells().size() <= col) {
                    tableRow.createCell();
                }

                XWPFTableCell cell = tableRow.getCell(col);

                // 清空旧内容
                cell.removeParagraph(0);

                // 写入新文本并设置字体样式为小四宋体(12pt)
                XWPFParagraph paragraph = cell.addParagraph();
                XWPFRun run = paragraph.createRun();
                String text = row < colData.size() ? colData.get(row) : "";
                run.setText(text);
                run.setFontFamily("宋体");
                run.setFontSize(10); // 小四:12pt
            }
        }
    }

    private String generateUniqueFileName() {
        long timestamp = System.currentTimeMillis();
        int randomNum = new Random().nextInt(10000);
        return timestamp + "_" + randomNum + ".docx";
    }


在这里插入图片描述
在这里插入图片描述

{
	"excelData": [
		[
			"水用量",
			"水泥用量",
			"水泥-种类",
			"水泥-细度",
			"水泥-28天抗压强度",
			"矿粉用量",
			"矿粉-细度",
			"矿粉-28天活性指数",
			"粉煤灰用量",
			"粉煤灰-细度",
			"粉煤灰-28天活性指数",
			"砂用量",
			"砂-细度",
			"砂-石粉含量",
			"石用量",
			"石-含泥量",
			"石-压碎指标值",
			"减水剂用量",
			"减水剂-含固量",
			"减水剂-水泥净浆流动度",
			"增效剂用量",
			"坍落度",
			"3天抗压强度",
			"7天抗压强度",
			"28天抗压强度"
		],
		[
			"150",
			"145",
			"0",
			"1.6",
			"57.7",
			"50",
			"3.9",
			"106",
			"90",
			"32.4",
			"73",
			"895",
			"2.84",
			"9.40",
			"1010",
			"0.92",
			"0",
			"10",
			"11.5",
			"190",
			"1.43",
			"205",
			"22.5",
			"31.8",
			"47.6"
		]

	]
}

网站公告

今日签到

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