积累知识库:POI操作word文档实现替换符替换文字

引入依赖

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

具体实现

准备替换实体:

@Data
@Builder
public class ReplaceParam {


    //占位符
    private String placeholder;
    //替换值
    private String replaceValue;
    //默认值
    private String defaultValue;
    //文字大小
    private Integer size;
    //字体样式
    private String fontFamily;
    //字体颜色
    private String color;
    //..........
}

具体实现:



public class POIWordUtil {

    public static File replace( File sourceFile,  File targetFile, List<ReplaceParam> replaceParams) {
        //创建文档
        XWPFDocument xwpfDocument = DocUtil.create(sourceFile);
        try (FileOutputStream outputStream = new FileOutputStream(targetFile)) {
            Map<String, ReplaceParam> replaceParamMap = replaceParams.stream().collect(Collectors.toMap(ReplaceParam::getPlaceholder, Function.identity()));
            for (IBodyElement iBodyElement : xwpfDocument.getBodyElements()) {
                //段落
                if (iBodyElement instanceof XWPFParagraph) {
                    XWPFParagraph xwpfParagraph = (XWPFParagraph) iBodyElement;
                    replaceText(replaceParamMap, xwpfParagraph);
                }
                //表格
                if (iBodyElement instanceof XWPFTable) {
                    //多层表格则需要一直嵌套
                    replaceTables(replaceParamMap,(XWPFTable)iBodyElement);
                }
            }
            xwpfDocument.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return targetFile;
    }

    /**
     * 处理表格问题,可能嵌套表格
     */
    private static void replaceTables(Map<String, ReplaceParam> map, XWPFTable xwpfTable) {
        for (XWPFTableRow row : xwpfTable.getRows()) {
            for (XWPFTableCell cell : row.getTableCells()) {
                List<IBodyElement> bodyElements = cell.getBodyElements();
                for (IBodyElement bodyElement : bodyElements) {
                    //表格中存在段落则进行段落替换
                    if (bodyElement instanceof XWPFParagraph) {
                        replaceText(map,  (XWPFParagraph) bodyElement);
                    }
                    if (bodyElement instanceof XWPFTable) {
                        replaceTables(map, (XWPFTable)bodyElement);
                    }
                }
            }
        }
    }

    /**
     * 文本替换--样式保留为原来的样式
     */
    private static void replaceText(Map<String, ReplaceParam> replaceParamMap, XWPFParagraph xwpfParagraph) {
        String text = xwpfParagraph.getParagraphText();
        if (StrUtil.isNotBlank(text) && text.contains("${")) {
            List<XWPFRun> runs = xwpfParagraph.getRuns();
            for (XWPFRun run : runs) {
                //替换文字和样式
                changeValue(run, replaceParamMap);
            }
        }
    }

    /**
     * 文字或者样式替换
     */
    private static void changeValue(XWPFRun run, Map<String, ReplaceParam> replaceParamMap) {
        Set<Map.Entry<String, ReplaceParam>> textSets = replaceParamMap.entrySet();
        for (Map.Entry<String, ReplaceParam> textSet : textSets) {
            //匹配模板与替换值 格式${key}
            String key =  textSet.getKey() ;
            ReplaceParam replaceParam = textSet.getValue();
            if (run.toString().contains(key)) {
                //替换值
                String replaceValue = replaceParam.getReplaceValue() == null ? replaceParam.getDefaultValue() : replaceParam.getReplaceValue();
                String value = run.toString().replace(key, replaceValue);
                run.setText(value,0);
                if (replaceParam.getSize() != null){
                    run.setFontSize(replaceParam.getSize());
                }
                if (replaceParam.getColor() != null){
                    run.setColor(replaceParam.getColor());
                }
                if (replaceParam.getFontFamily() != null){
                    run.setFontFamily(replaceParam.getFontFamily());
                }
                //...........................
            }
        }
    }


    public static void main(String[] args) {
        ReplaceParam param1 = ReplaceParam.builder().placeholder("${add1}").replaceValue("星期一").size(40).build();
        ReplaceParam param2 = ReplaceParam.builder().placeholder("${add2}").replaceValue("星期二").build();
        ReplaceParam param3 = ReplaceParam.builder().placeholder("${add3}").replaceValue("星期三").size(30).build();
        ReplaceParam param4 = ReplaceParam.builder().placeholder("${add4}").replaceValue("星期四").size(22).build();
        ReplaceParam param5 = ReplaceParam.builder().placeholder("${add5}").replaceValue("星期五").build();
        ReplaceParam param6 = ReplaceParam.builder().placeholder("${add6}").replaceValue("星期六").build();
        ReplaceParam param7 = ReplaceParam.builder().placeholder("${add7}").replaceValue("星期日").build();

        List<ReplaceParam> list = new ArrayList<>();
        list.add(param1);
        list.add(param2);
        list.add(param3);
        list.add(param4);
        list.add(param5);
        list.add(param6);
        list.add(param7);
        File sourceFile = new File("C:\\Users\\a\\Desktop\\study\\测试替换文档.docx");
        File targetFile = new File("C:\\Users\\a\\Desktop\\study\\替换文档.docx");
         POIWordUtil.replace(sourceFile, targetFile, list);

    }
}

原始模板:

替换后:

注意

如果出现${替换符}出现没在一起的情况,像这种:

解决办法:

把 ${替换符} 先在记事本上连续写出来,再粘贴到文档中

  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Apache POI库来操作Word文档,下面是一个示例代码,演示如何使用POIWord文档中写入文字和图片。 ```java import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.poi.xwpf.usermodel.*; import org.apache.poi.util.IOUtils; public class WordWriter { public static void main(String[] args) throws Exception { // 创建一个新的Word文档对象 XWPFDocument doc = new XWPFDocument(); // 创建一个新的段落 XWPFParagraph para = doc.createParagraph(); // 创建一个新的文本运行 XWPFRun run = para.createRun(); // 设置文本运行的内容 run.setText("Hello World!"); // 添加一个换行 para.createRun().addBreak(); // 读取图片文件 FileInputStream fis = new FileInputStream(new File("image.jpg")); // 将图片文件转换为二进制数组 byte[] bytes = IOUtils.toByteArray(fis); // 关闭文件输入流 fis.close(); // 创建一个新的段落 para = doc.createParagraph(); // 创建一个新的文本运行 run = para.createRun(); // 插入图片 run.addPicture(bytes, XWPFDocument.PICTURE_TYPE_JPEG, "image.jpg", Units.toEMU(300), Units.toEMU(200)); // 保存Word文档 FileOutputStream fos = new FileOutputStream(new File("output.docx")); doc.write(fos); fos.close(); } } ``` 上述代码中,首先创建了一个新的Word文档对象。然后创建了一个新的段落和文本运行,并设置了文本运行的内容。接着添加了一个换行。接下来,读取了一个图片文件,将其转换为二进制数组,并插入到一个新的段落中。最后,将Word文档保存到文件中。 注意,在实际使用中,需要根据具体情况设置图片的类型和大小。此外,还可以设置图片的位置、对齐方式等属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值