Java word template placeholder replacement (${xx}) replacement

Preface

I recently received a development requirement like this. Each company will have its own contract template. The content of the template needs to come from online data, which is what we understand by the title.

1. Template diagram

Insert image description here

2. Effect drawing

Insert image description here

特此说明:上述模版内容均为测试数据,不具备任何真实性。  

3. Code implementation

3.1maven dependencies

		<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.5.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-excelant</artifactId>
            <version>3.12</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.12</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.8</version>
        </dependency>

3.2 Core tool categories

public void exportWord(String contractId, String bizId,HttpServletResponse response) throws Exception {
    
    
        ContractInfoVo contractInfoVo = remoteContractInfoService.getById(contractId).getData();
        if (Objects.nonNull(contractInfoVo)){
    
    
            new ZsqyException("合同数据异常");
        }

        List<CAttachment> list = attachmentService.list(
                new LambdaQueryWrapper<CAttachment>()
                        .eq(CAttachment::getBizId, bizId));
        if (list.size() == 0) {
    
    
            new ZsqyException("当前模版数据下未上传模版文件");
        }
        CAttachment attachment = list.get(0);
        InputStream inputStream = minioUtil.download(attachment.getFilePath(), attachment.getFileMd5Name());
        Map<String, String> pamraMap =getValueMap(contractInfoVo);
        XWPFDocument document = new XWPFDocument(inputStream);
        Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();

        List<XWPFParagraph> paragraphList=new ArrayList<>();
        while (itPara.hasNext()) {
    
    
            XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
            List<XWPFRun> runs = paragraph.getRuns();
            for (int i = 0; i < runs.size(); i++) {
    
    
                String oneparaString = runs.get(i).getText(runs.get(i).getTextPosition());
                if (StringUtils.isBlank(oneparaString)){
    
    
                    continue;
                }
                oneparaString=oneparaString.trim();
                for (Map.Entry<String, String> entry : pamraMap.entrySet()) {
    
    
                    if (oneparaString.contains(entry.getKey())) {
    
    
                        oneparaString = oneparaString.replace(entry.getKey(), entry.getValue());
                    }

                }
                runs.get(i).setText(oneparaString, 0);
            }
            paragraphList.add(paragraph);
        }
        replaceWordText(paragraphList,pamraMap);
        response.reset();
        response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(contractInfoVo.getContractName()+".docx", "UTF-8"));
        response.setContentType("application/octet-stream");
        OutputStream out = response.getOutputStream();
        document.write(out);//将word对象内容写入输出流
    }
    public Map<String, String> getValueMap(ContractInfoVo contractInfoVo){
    
    
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Map<String, String> map=new HashMap<>();
        map.put("${
    
    {合同简称}}", isEmpty(contractInfoVo.getContractName()));
        ........
		return map
}

Code interpretation
1. Query business data
2. Get the template file from minio
3. Put the input stream in the document into the XWPFDocument object to parse, and get the specific row object
4. After getting the row object, traverse and match the placeholder ( ${xx}).
5. The placeholder content is replaced successfully, the stream is output, and the browser downloads.

Guess you like

Origin blog.csdn.net/weixin_45116026/article/details/130603329