1. word模板示例
2. 引入pom
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.2</version>
</dependency>
tips :poi跟poi-ooxml版本最好一致,否则会报错
3. Java代码
public class XwpfdUtil {
public static ResponseEntity<byte[]> changWord(String inputUrl, String name, Map<String, String> textMap) throws IOException {
//模板转换默认成功
byte[] finalBytes = new byte[0];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
String fileName = null;
try {
//获取docx解析对象
InputStream is = AccidentConsultationServiceImpl.class.getClassLoader().getResourceAsStream(inputUrl);
XWPFDocument document = new XWPFDocument(is);
//解析替换表格对象
changeTable(document, textMap);
//生成新的word
outputStream = new ByteArrayOutputStream();
document.write(outputStream);
finalBytes = outputStream.toByteArray();
fileName = URLEncoder.encode(name, "UTF-8");
// 文件流写出到浏览器
} catch (IOException e) {
e.printStackTrace();
} finally {
close(outputStream);
}
return flushToResp(fileName, "docx", finalBytes);
}
public static ResponseEntity<byte[]> flushToResp(String fileName, String suffix, byte[] bytes) {
if (bytes == null || bytes.length == 0) {
throw new IllegalArgumentException("文件生成失败, 数据不能为空");
}
HttpHeaders headers = new HttpHeaders();
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
String encodedFileName = null;
try {
encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
headers.add("Content-Disposition", String.format("attachment;filename=%s.%s;", encodedFileName, suffix));
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
return ResponseEntity.ok().headers(headers).contentLength(bytes.length).contentType(MediaType.APPLICATION_OCTET_STREAM).body(bytes);
}
public static void changeTable(XWPFDocument document, Map<String, String> textMap) {
//获取表格对象集合
List<XWPFTable> tables = document.getTables();
//只会有一个表格对象,所以取第一个表格对象
List<XWPFTableRow> rows = tables.get(0).getRows();
//遍历表格,并替换模板
eachTable(rows, textMap);
}
/**
* 遍历表格
*
* @param rows 表格行对象
* @param textMap 需要替换的信息集合
*/
public static void eachTable(List<XWPFTableRow> rows, Map<String, String> textMap) {
for (XWPFTableRow row : rows) {
//得到表格每一行的所有表格
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
//判断单元格是否需要替换
if (checkText(cell.getText())) {
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
run.setText(changeValue(run.toString(), textMap), 0);
}
}
}
}
}
}
/**
* 判断文本中时候包含$
*
* @param text 文本
* @return 包含返回true, 不包含返回false
*/
public static boolean checkText(String text) {
boolean check = false;
if (text.indexOf("$") != -1) {
check = true;
}
return check;
}
/**
* 匹配传入信息集合与模板
*
* @param value 模板需要替换的区域
* @param textMap 传入信息集合
* @return 模板需要替换区域信息集合对应值
*/
public static String changeValue(String value, Map<String, String> textMap) {
Set<Map.Entry<String, String>> textSets = textMap.entrySet();
for (Map.Entry<String, String> textSet : textSets) {
//匹配模板与替换值 格式${key}
String key = "${" + textSet.getKey() + "}";
if (value.indexOf(key) != -1) {
value = textSet.getValue();
}
}
//模板未匹配到区域替换为空
if (checkText(value)) {
value = "无";
}
return value;
}
/**
* 关闭输入流
*
* @param is
*/
public static void close(InputStream is) {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 关闭输出流
*
* @param os
*/
public static void close(OutputStream os) {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4. 方法调用
Map<String, String> params = new HashMap<String, String>();
//替换的值
params.put("personnelNames", po.getPersonnelNames());
params.put("deptName")
XwpfdUtil.changWord(inputUrl, "意见", params);