Springboot integrates poi operation word to realize batch modification of multi-file content


1. What is POI?

Apache POI is a free and open source cross-platform Java API written in Java, which provides APIs for Java programs to read and write Microsoft Office format files.
This article mainly uses POI to operate XWPFDocument to read and write word documents.

Related Links:
1. Short sample tutorial of Apache POI Word (docx) http://deepoove.com/poi-tl/apache-poi-guide.html

2. poi-tl will perfectly retain the style in the template in the generated document, and you can also set the style for the label, and the style of the label will be applied to the replaced text, so you can focus on the template design.
http://deepoove.com/poi-tl/

Two, XWPFDocument attribute introduction

insert image description here

2.1 pom.xml file

The code is as follows (example):

<!--poi依赖-->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>5.0.0</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>5.0.0</version>
</dependency>
<!-- web项目 -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--thymeleaf模板引擎-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2.2 Control layer

@Controller
public class TestController {
    
    
	@GetMapping("/")
    public String test(){
    
    
        return "replaceWord";
    }

	@GetMapping("/replaceWord")
    public String inputParam(String input,String output,String source,String target) throws IOException {
    
    
        File file = new File(input);
        File readFile;
        if(file.isDirectory()) {
    
    
            System.out.println("正在读取"+ input +"目录....");
            String[] list = file.list();
            for(int i = 0; i< Objects.requireNonNull(list).length; i++) {
    
    
                readFile = new File(input +"/"+list[i]);
                if(readFile.isDirectory()) {
    
    
                    System.out.println("文件夹:"+list[i]);
                }else {
    
    
                    System.out.println("正在读取"+ input + "/" + list[i]);
                    FileInputStream in = new FileInputStream(readFile);
                    XWPFDocument doc = new XWPFDocument(in);

                    //正文段落-获取所有段落 ======== 替换段落文字
                    List<XWPFParagraph> paragraphs = doc.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
    
    
                        if(!paragraph.getParagraphText().contains(source)){
    
    
                            continue;
                        }
                        //获取段落中的runs
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (int i1 = 0; i1 < runs.size(); i1++) {
    
    
                            XWPFRun run = runs.get(i1);
                            String runText = run.toString();
                            if(runText.contains(source)){
    
    
                                runText = runText.replaceAll(source, target);
                                // 直接调用 XWPFRun 的 setText() 方法设置文本时,在底层会重新创建一个 XWPFRun,把文本附加在当前文本后面,
                                // 所以我们不能直接设值,需要先删除当前 run, 然后再自己手动插入一个新的 run
                                paragraph.removeRun(i1);
                                paragraph.insertNewRun(i1).setText(runText);
                            }
                        }
                    }

                    //获得所有的表格  ------ 替换表格文字
                    List<XWPFTable> tables = doc.getTables();
                    for (XWPFTable table : tables) {
    
    
                        //一个表格包含多行
                        List<XWPFTableRow> rows = table.getRows();
                        for (XWPFTableRow row : rows) {
    
    
                            //一行包含多列
                            List<XWPFTableCell> tableCells = row.getTableCells();
                            //一行一列,横纵坐标确定一个 XWPFTableCell
                            //表格中的一格相当于一个没有页眉和页脚的文档
                            for (XWPFTableCell tableCell : tableCells) {
    
    
                                String text = tableCell.getText();
                                if (!StringUtils.isEmpty(text) && Objects.equals(text, source)) {
    
    
                                    //setText底层是追加,所以要删除删除原来的段落
                                    tableCell.removeParagraph(0);
                                    //设置段落的样式,行间距
                                    XWPFParagraph para = tableCell.addParagraph();
                                    para.setSpacingBetween(1);
                                    //赋值
                                    tableCell.setText(target);
                                }
                            }
                        }
                    }
                    OutputStream out = Files.newOutputStream(Paths.get(output+"/"+list[i]));
                    // 输出
                    doc.write(out);
                    System.out.println("正在输出文件:" + output + "/" + list[i]);
                    in.close();
                    out.close();
                }
            }
        }else {
    
    
            System.out.println(input +"不是一个目录。");
        }
        return "replaceWord";
    }
}

2.3 replaceWord.html file

<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org/">
<head>
    <meta charset="UTF-8">
    <title>批量修改word文字 只测试过docx</title>
</head>
<body>
    <form method="get" action="/replaceWord">
        <label>
            选择导入文件夹:
            <input type="text" th:name="input" required>
        </label><br/>
        <label>
            选择输出文件夹:
            <input type="text" th:name="output" required>
        </label><br/>
        <label>
            需要修改的内容:
        <input type="text" th:name="source" required>
        </label><br/>
        <label>
            修改为什么内容:
            <input type="text" th:name="target" required>
        </label><br/>
        <button type="submit">进行替换</button>
    </form>
</body>
</html>

Access the front-end project:
insert image description here


Summarize

The above case achieves batch replacement of the contents of the .docx files at the same level under the folder. The case is exposed to other users, so a simple html is written, and the developer can directly call it with the main function.

Guess you like

Origin blog.csdn.net/weixin_45549188/article/details/129416890