根据自定义模板导出doc文件,处理占位替换富文本标签问题

准备工作:

 创建一个需要替换的docx文件,放到某个项目路径下,确保程序可以拿到这个文件

引入pom文件

		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>${poi.version}</version>
		</dependency>
        <!--word工具类-->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.9.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi-ooxml</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.4</version>
        </dependency>
        <!--html渲染插件-->
        <dependency>
            <groupId>io.github.draco1023</groupId>
            <artifactId>poi-tl-ext</artifactId>
            <version>0.3.3</version>
            <exclusions>
                <exclusion>
                    <groupId>com.deepoove</groupId>
                    <artifactId>poi-tl</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>ooxml-schemas</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--样式依赖-->
        <dependency>
            <groupId>org.w3c.css</groupId>
            <artifactId>sac</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.cssparser</groupId>
            <artifactId>cssparser</artifactId>
            <version>0.9.29</version>
        </dependency>

工具类

public class ReplaceUtils {
    public static String replace(String templatePath, String outputPath, Map<String, String> replacements) throws IOException {
        // 读取模板文件
        FileInputStream fis = new FileInputStream(templatePath);
        XWPFDocument document = new XWPFDocument(fis);
        fis.close();

        // 替换文本
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            for (XWPFRun run : paragraph.getRuns()) {
                String text = run.getText(0);
                if (text != null) {
                    for (Map.Entry<String, String> entry : replacements.entrySet()) {
                        String placeholder = "${" + entry.getKey() + "}";
                        if (text.contains(placeholder)) {
                            text = text.replace(placeholder, entry.getValue());
                            run.setText(text, 0);
                        }
                    }
                }
            }
        }

        // 导出新文件
        FileOutputStream fos = new FileOutputStream(outputPath);
        document.write(fos);
        fos.close();

        return outputPath;
    }
}

使用事例

// 定义要替换的文本
Map<String, String> replacements = new HashMap<>();
replacements.put("documentTitle", 测试");
replacements.put("documentSymbol", "测试");
replacements.put("year", "2023");
replacements.put("serialNumber", "666");
replacements.put("contentTitle", "测试");
replacements.put("mainText", "测试");
replacements.put("inscription", "测试");
replacements.put("time", "2023年8月29日");

// 替换文本并输出到新文件
String templatePath = "/path/to/template.docx";
String outputPath = "/path/to/output.docx";
ReplaceUtils.replace(templatePath, outputPath, replacements);

 大致思路,创建一个实体类,实体类字段对应文件中需要替换的文本去占位,然后只需要拿着实体类参数调用工具类就可以了

续:

这样实际会出现一个问题,当${mainText}为富文本时,则会出现导出文件内容带有富文本标签例如<p></p><br></br>此问题可以做一个处理,最终代码:

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.sdecloud.documentManagement.entity.TDocumentContent;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.ddr.poi.html.HtmlRenderPolicy;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

public class ReplaceUtils {

    public static String doc(TDocumentContent a) throws IOException {
        // 读取模板文件
        String projectPath = System.getProperty("user.dir");
        File file = new File(projectPath + "/docTest.docx");
        FileInputStream fis = new FileInputStream(file);
        XWPFDocument document = new XWPFDocument(fis);
        fis.close();



        // 替换文本
        for (XWPFParagraph paragraph : document.getParagraphs()) {
            for (XWPFRun run : paragraph.getRuns()) {
                String text = run.getText(0);
                if (text != null) {
                    if (text.contains("${documentTitle}")) {
                        text = text.replace("${documentTitle}", a.getDocumentTitle());
                        run.setText(text, 0);
                    }
                    if (text.contains("${documentSymbol}")) {
                        text = text.replace("${documentSymbol}", a.getDocumentSymbol());
                        run.setText(text, 0);
                    }
                    if (text.contains("${year}")) {
                        text = text.replace("${year}", a.getYear().toString());
                        run.setText(text, 0);
                    }
                    if (text.contains("${serialNumber}")) {
                        text = text.replace("${serialNumber}", a.getSerialNumber().toString());
                        run.setText(text, 0);
                    }
                    if (text.contains("${contentTitle}")) {
                        text = text.replace("${contentTitle}", a.getContentTitle());
                        run.setText(text, 0);
                    }
//                    if (text.contains("${mainText}")) {
//                        text = text.replace("${mainText}", a.getMainText());
//                        run.setText(text, 0);
//                    }
                    if (text.contains("${inscription}")) {
                        text = text.replace("${inscription}", a.getInscription());
                        run.setText(text, 0);
                    }
                    if (text.contains("${time}")) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
                        String dateString = sdf.format(a.getTime());
                        text = text.replace("${time}", dateString);
                        run.setText(text, 0);
                    }
                }
            }
        }

        // 导出新文件
        //生成uuid作为文件名称

        String docNameTemp = a.getDocumentTitle()+"_temp" + ".docx";
        String outputPathTemp = projectPath +"/files/temp/"+ docNameTemp;
        FileOutputStream fos = new FileOutputStream(outputPathTemp);
        document.write(fos);
        fos.close();
        return dealRichText(a,outputPathTemp);
    }

    /**
      * @Description: 处理富文本数据
     */
    private static String dealRichText(TDocumentContent a,String outputPathTemp){
        StringBuffer sbf = new StringBuffer();
        sbf.append("<html><body>");
        sbf.append(a.getMainText());
        sbf.append("</body></html");
        Map map = new HashMap<>(1);
        map.put("mainText",sbf.toString());
        // html渲染插件
        HtmlRenderPolicy htmlRenderPolicy = new HtmlRenderPolicy();
        // 第一个案例
        Configure configure = Configure.builder()
                .bind("mainText", htmlRenderPolicy)
                .build();
        XWPFTemplate template = XWPFTemplate.compile(outputPathTemp, configure).render(map);
        // 读取模板文件
        String projectPath = System.getProperty("user.dir");
        String docName = a.getDocumentTitle() + ".docx";
        String outputPath = projectPath +"/files/temp/"+ docName;
        try {
            template.writeToFile(outputPath);
            template.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return docName;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值