不多解释看代码就明白了
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-examples</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-excelant</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.1</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
因为是演示所以准备两份 为了演示 doc 和docx都支持
文件内容如下:
${} 就是占位符 { } 内的是变量用于使用poi时候替换成实际值
将模板放入resources下面
package com.word.utils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.xwpf.usermodel.*;
import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WordTemplateParse {
public enum WordType {
doc, docx
}
/** * * @param data 替换的数据 * @param tempFileStream 模板文件 * @param targetFileStream 输出的文件 * @param type 文件;类型 * @return */
public static Boolean generate(Map<String, String> data, String tempFileStream, String targetFileStream, WordType type) throws FileNotFoundException {
try {
InputStream in=new FileInputStream(tempFileStream);
OutputStream outputStream= new FileOutputStream(targetFileStream);
if (WordType.docx.equals(type) ) {
return generate_docx(data, in, outputStream);
} else if (WordType.doc.equals(type)){
return generate_doc(data, in, outputStream);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return false;
}
private static Boolean generate_docx(Map<String, String> data, InputStream tempFileStream, OutputStream targetFileStream) {
try {
// 加载磁盘的 temp.docx 文件
XWPFDocument document = new XWPFDocument(tempFileStream);
// 解析文档中的【段落】的插值 ${..}
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
String text = paragraph.getText();
// 如果该单元格为空就遍历下一个
if (text == null || "".equals(text)) {
continue;
}
// 得到解析 ${...} 后的内容
String newText = replaceByMap(text, null, data);
// 判断值是否改变,如果没有改变就不做处理
if (!text.equals(newText)) {
int runSize = paragraph.getRuns().size();
// 清空该段落所有值
for (int i = 0; i < runSize; i++) {
paragraph.removeRun(i);
}
XWPFRun run = paragraph.createRun();
run.setText(newText);
}
}
// 解析文档中【表格】的插值 ${..}
// 获取文档中的表格
List<XWPFTable> tables = document.getTables();
for (XWPFTable table : tables) {
// 得到所有行的集合并遍历
List<XWPFTableRow> rows = table.getRows();
for (XWPFTableRow row : rows) {
// 得到所有列的集合并遍历
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
// 获取整个单元格的值
String text = cell.getText();
// 如果该单元格为空就遍历下一个
if (text == null || "".equals(text)) {
continue;
}
// 得到解析 ${...} 后的内容
String newText = replaceByMap(text, null, data);
// 判断值是否改变,如果没有改变就不做处理
if (!text.equals(newText)) {
// 清空单元格内容
int paragraphsNums = cell.getParagraphs().size();
for (int i = 0; i < paragraphsNums; i++) {
cell.removeParagraph(i);
}
cell.setText(newText);
}
}
}
}
// 将文档写入目标文件中
document.write(targetFileStream);
// 关闭流
tempFileStream.close();
targetFileStream.close();
document.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private static Boolean generate_doc(Map<String, String> data, InputStream tempFileStream, OutputStream targetFileStream) {
try {
// 加载磁盘的 temp.docx 文件
HWPFDocument document = new HWPFDocument(tempFileStream);
Range range = document.getRange();
//把range范围内的${reportDate}替换为当前的日期
for (Map.Entry<String, String> stringStringEntry : data.entrySet()) {
range.replaceText("${" + stringStringEntry.getKey() + "}", stringStringEntry.getValue());
}
//把doc输出到输出流中
document.write(targetFileStream);
targetFileStream.close();
tempFileStream.close();
document.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
// 如果根据正则表达式规则匹配成功则替换,否则返回原值
private static String replaceByMap(String content, String regex, Map<String, String> map) {
// 匹配插值 ${...}
if (regex == null) {
regex = "\\$\\{[\\w\\W]+\\}";
}
// 初始化正则
Pattern p = Pattern.compile(regex);
Matcher matcher = p.matcher(content);
// 找到匹配的内容的 key
if (matcher.find()) {
// 提前key值
String matchContent = matcher.group(0);
int start = matchContent.indexOf("{");
int end = matchContent.indexOf("}");
// 获取key
String key = matchContent.substring(start + 1, end);
// 从map中取出key的值
String value = map.get(key);
if (value == null) {
return content;
}
// 得到替换后的值
String newContent = matcher.replaceAll(value);
return newContent;
}
// 没有匹配到,返回原值
return content;
}
}
获取resources的路径工具类
package com.word.utils;
import org.springframework.util.ResourceUtils;
import java.io.File;
import java.io.FileNotFoundException;
/** * @Description: 项目静态资源文件工具类 * 仅可用于包含在web项目中的资源文件路径,资源文件必须放置于 web 模块下 * @Author: junqiang.lu * @Date: 2019/1/4 */
public class ResourceFileUtil {
/** * 获取资源绝对路径 (就只使用这个 ) * * @param relativePath 资源文件相对路径(相对于 resources路径,路径 + 文件名) * eg: "templates/pdf_export_demo.ftl" * @return * @throws FileNotFoundException */
public static String getAbsolutePath(String relativePath) throws FileNotFoundException {
return getFile(relativePath).getAbsolutePath();
}
/** * 获取资源文件 * * @param relativePath 资源文件相对路径(相对于 resources路径,路径 + 文件名) * eg: "templates/pdf_export_demo.ftl" * @return * @throws FileNotFoundException */
public static File getFile(String relativePath) throws FileNotFoundException {
if (relativePath == null || relativePath.length() == 0) {
return null;
}
if (relativePath.startsWith("/")) {
relativePath = relativePath.substring(1);
}
File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX
+ relativePath);
return file;
}
/** * 获取资源父级目录 * * @param relativePath 资源文件相对路径(相对于 resources路径,路径 + 文件名) * eg: "templates/pdf_export_demo.ftl" * @return * @throws FileNotFoundException */
public static String getParent(String relativePath) throws FileNotFoundException {
return getFile(relativePath).getParent();
}
/** * 获取资源文件名 * * @param relativePath 资源文件相对路径(相对于 resources路径,路径 + 文件名) * eg: "templates/pdf_export_demo.ftl" * @return * @throws FileNotFoundException */
public static String getFileName(String relativePath) throws FileNotFoundException {
return getFile(relativePath).getName();
}
}
package com.word.utils;
import org.junit.Test;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class WordTemplateParseText {
@Test
public void test01() throws FileNotFoundException {
// 数据
TreeMap<String, String> data = new TreeMap<String, String>();
data.put("yue1", "33");
data.put("yue2", "22");
data.put("yue3", "55");
data.put("yue4", "12");
data.put("yue5", "2");
data.put("yue6", "151");
data.put("yue7", "33");
data.put("yue8", "34");
data.put("yue9", "123");
data.put("yue10", "15");
data.put("yue11", "2");
data.put("yue12", "10");
// 加载模型【模型】
String absolutePath = ResourceFileUtil.getAbsolutePath("temp.docx"); //模板位置
// 输出位置【输出】 生成新的word位置和模板在一个目录下
String newabsolutePath = ResourceFileUtil.getParent("temp.docx")+ File.separator+"new_temp.docx";
System.out.println(newabsolutePath);
Boolean generate = WordTemplateParse.generate(data, absolutePath, newabsolutePath, WordTemplateParse.WordType.docx);
System.out.println(generate);
}
@Test
public void test011() throws IOException {
// 数据
TreeMap<String, String> data = new TreeMap<String, String>();
data.put("yue1", "33");
data.put("yue2", "22");
data.put("yue3", "55");
data.put("yue4", "12");
data.put("yue5", "2");
data.put("yue6", "151");
data.put("yue7", "33");
data.put("yue8", "34");
data.put("yue9", "123");
data.put("yue10", "15");
data.put("yue11", "2");
data.put("yue12", "10");
// 加载模型【模型】
String absolutePath = ResourceFileUtil.getAbsolutePath("temp1.doc"); //模板位置
// 输出位置【输出】 生成新的word位置和模板在一个目录下
String newabsolutePath = ResourceFileUtil.getParent("temp1.doc")+ File.separator+"new_temp1.doc";
System.out.println(newabsolutePath);
Boolean generate = WordTemplateParse.generate(data, absolutePath, newabsolutePath, WordTemplateParse.WordType.doc);
System.out.println(generate);
}
}
运行上面代码后会在target下面生成对应的word
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_45203607/article/details/120249134
内容来源于网络,如有侵权,请联系作者删除!