poi操作word文档的合并与参数替换


@Service
public class MultiDocxServiceImpl implements MultiDocxService {
    private final Logger log = LoggerFactory.getLogger(MultiDocxServiceImpl.class);
    @Resource
    private FileServerUtil fileServerUtil;
    @Resource
    private PropertiesUtils propertiesUtils;
    public final String DOCX_NAME = "_default.docx";
    @Value("${cache.expire:86400}")
    private Long expire;
    @Value("${word.title.fontFamily:宋体}")
    private String fontFamily;
    @Value("${word.title.fontSize:10}")
    private Integer fontSize;

    @Override
    public String merge(MultiDocxParams multiDocxParams) {
        log.info("入参:{}", JSON.toJSONString(multiDocxParams));
        String fileName = multiDocxParams.getFileName();
        if(StringUtils.isBlank(fileName)){
            fileName = UUIDGenerator.getUUID() + DOCX_NAME;
        }else{
            fileName = multiDocxParams.getFileName();
        }
        String localPath = propertiesUtils.getCommonYml("upload.path") + fileName;
        NiceXWPFDocument mergeDocument = null;
        FileOutputStream out = null;
        try {
            FileUtil.mkParentDirs(localPath);
            out = new FileOutputStream(localPath);
            mergeDocument = mergeDocument(multiDocxParams);
            mergeDocument.write(out);

            return fileServerUtil.restTemplateUploadFile(new File(localPath));
        } catch (Exception e) {
            log.error("合并异常了",e);
            throw new CustomException(ResponseCode.FAILED.getCode(),e.getMessage());
        } finally {
            try {
                if(mergeDocument!=null) {
                    mergeDocument.close();
                }
                if(out!=null) {
                    out.close();
                }
            } catch (IOException e) {
                log.error("关闭文件异常",e);
                log.error("关闭文件失败,文件位置:{}",localPath);
            }
            try {
                // 删除临时docx文件
                File file = new File(localPath);
                file.delete();
            } catch (Exception e) {
                log.error("删除临时文件异常",e);
                log.error("删除临时文件失败,文件位置:{}",localPath);
            }
        }
    }

    private NiceXWPFDocument mergeDocument(MultiDocxParams multiDocxParams) throws Exception {
        List<DocxFileParam> docxFileParamList = multiDocxParams.getDocxFileParamList();
        NiceXWPFDocument newDoc = null;
        for (DocxFileParam docxFileParam : docxFileParamList) {
            NiceXWPFDocument document = getDocument(docxFileParam.getFileId());
            NiceXWPFDocument niceXWPFDocument = word2007ParamReplace(document, changeMap(docxFileParam.getParams()));
            if (newDoc == null) {
                newDoc = niceXWPFDocument;
            } else {
                //添加段落
                XWPFParagraph p = newDoc.createParagraph();
                p.setPageBreak(true);
                if(StringUtils.isNotBlank(docxFileParam.getTitle())) {
                    XWPFRun run = p.createRun();
                    run.setFontFamily(fontFamily);
                    run.setFontSize(fontSize);
                    run.setText(docxFileParam.getTitle());
                }

                newDoc = newDoc.merge(niceXWPFDocument);
            }
        }
        return newDoc;
    }


    private NiceXWPFDocument getDocument(Long fileId) throws Exception {
        String name = String.valueOf(fileId);
        Object cache = Cache.get(name);
        NiceXWPFDocument document = null;
        if (cache != null) {
            byte[] b = (byte[]) cache;
            document = new NiceXWPFDocument(toInputStream(b));
        } else {
            byte[] buf = fileServerUtil.restTemplateDownloadFile(fileId);
            Cache.put(name, buf, expire*1000);
            document = new NiceXWPFDocument(toInputStream(buf));
        }
        return document;
    }

    public InputStream toInputStream(byte[] b) {
        return new ByteArrayInputStream(b);
    }

    private Map<String, String> changeMap(Map<String, String> paramsMap) {
        if (paramsMap == null || paramsMap.isEmpty()) {
            return paramsMap;
        }
        Map<String, String> changeMap = new HashMap<>();
        Set<String> keys = paramsMap.keySet();
        for (String key : keys) {
            changeMap.put("${" + key + "}", StringUtils.defaultIfEmpty(paramsMap.get(key),""));
        }
        return changeMap;
    }

    private NiceXWPFDocument word2007ParamReplace(NiceXWPFDocument document, Map<String, String> paramsMap) {
        if (paramsMap == null || paramsMap.isEmpty()) {
            return document;
        }
        // 替换段落中的指定文字
        Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();

        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(0);
                if (oneparaString != null && !"".equals(oneparaString)) {
                    for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                        oneparaString = oneparaString.replace(entry.getKey(), entry.getValue());
                        runs.get(i).setText(oneparaString, 0);
                    }
                }
            }
        }

        // 替换表格中的指定文字
        Iterator<XWPFTable> itTable = document.getTablesIterator();
        while (itTable.hasNext()) {
            XWPFTable table = (XWPFTable) itTable.next();
            int rcount = table.getNumberOfRows();
            for (int i = 0; i < rcount; i++) {
                XWPFTableRow row = table.getRow(i);
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
                            String oneparaString = run.getText(0);
                            if (oneparaString != null && !"".equals(oneparaString.trim())) {
                                for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                                    oneparaString = oneparaString.replace(entry.getKey(), entry.getValue());
                                    run.setText(oneparaString, 0);
                                }
                            }
                        }
                    }
                }
            }
        }
        return document;
    }
<dependency>
	<groupId>com.deepoove</groupId>
	<artifactId>poi-tl</artifactId>
	<version>1.9.1</version>
</dependency>
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "DocxFileParam对象", description = "DocxFileParam对象")
public class DocxFileParam {
    @ApiModelProperty(value = "word文件ID")
    @NotNull(message = "word文件ID不能为空")
    private Long fileId;
    @ApiModelProperty(value = "word文件中参数列表")
    private Map<String, String> params;
    @ApiModelProperty(value = "抬头title,可以为空")
    private String title;
}
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "MultiDocxParams对象", description = "MultiDocxParams对象")
public class MultiDocxParams {
    @ApiModelProperty(value = "上传到文件服务器的名称,不填则自动生成")
    private String fileName;
    @ApiModelProperty(value = "word列表")
    @Size(min = 1,message = "word文件列表至少1个")
    private List<DocxFileParam> docxFileParamList;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
合并多个 Word 文件,你可以使用 poi-tl 提供的方法来实现。以下是一个简单的示例: ```java import org.apache.poi.xwpf.usermodel.*; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import java.io.*; import java.util.List; public class WordMergeExample { public static void main(String[] args) { try { // 创建一个新的空白文档 XWPFDocument mergedDocument = new XWPFDocument(); // 读取第一个 Word 文件 XWPFDocument doc1 = new XWPFDocument(new FileInputStream("file1.docx")); // 复制第一个 Word 文件的内容到合并文档中 copyContent(doc1, mergedDocument); // 读取第二个 Word 文件 XWPFDocument doc2 = new XWPFDocument(new FileInputStream("file2.docx")); // 复制第二个 Word 文件的内容到合并文档中 copyContent(doc2, mergedDocument); // 保存合并后的文档 FileOutputStream outputStream = new FileOutputStream("merged.docx"); mergedDocument.write(outputStream); outputStream.close(); System.out.println("合并完成!"); } catch (IOException | InvalidFormatException e) { e.printStackTrace(); } } private static void copyContent(XWPFDocument sourceDoc, XWPFDocument targetDoc) { List<XWPFParagraph> paragraphs = sourceDoc.getParagraphs(); for (XWPFParagraph paragraph : paragraphs) { targetDoc.createParagraph().createRun().setText(paragraph.getText()); } } } ``` 在上面的示例中,我们首先创建了一个空白的目标文档 `mergedDocument`,然后使用 `copyContent` 方法将每个源文档的内容复制到目标文档中。最后,将目标文档保存为一个新的合并后的 Word 文件。 你需要将示例中的 `"file1.docx"` 和 `"file2.docx"` 替换为你要合并的实际文件路径。根据你的需求,你可以调整代码来处理更多的 Word 文件。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值