java基于POI实现向word模板填充数据
在做项目的时候遇到需要将多张表单导出为word,就想到了这个方法。
注意:XWPFDocument不支持doc类型文档,做模板的时候要另存为docx。
示例模板:
填充结果:
maven工程在pom.xml文件引入依赖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.0</version>
</dependency>
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFFooter;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
/**
* 替换段落里面的变量
* @param paragraph
* @param map
*/
public static void replaceParagraph(XWPFParagraph paragraph,Map<String,Object> map){
List<XWPFRun> runs = paragraph.getRuns();
for (int i = 0; i < runs.size(); i++) {
XWPFRun run = runs.get(i);
String tkey = run.toString();
if(tkey==null){
return;
}
for (String key : map.keySet()) {
if(tkey.equals(key)){
int size = run.getFontSize();
if(size==-1){
size=14;
}
String fontFamily = run.getFontFamily();
//因为直接调用setText()方法替换文本时,会在底层重新创建一个run,所以在设置文本之前要先删除当前run
paragraph.removeRun(i);
if(map!=null && map.get(key)!=null){
String runText = map.get(key).toString();
if(runText!=null){
if(runText.indexOf("\r\n")!=-1){
String[] texts = runText.split("\r\n");
List<String> tmp = new ArrayList<>();
for (String text : texts) {
if(text!=null && text.length()!=0){
tmp.add(text);
}
}
texts = tmp.toArray(new String[0]);
for (int n = 0; n < texts.length; n++) {
XWPFRun newRun = paragraph.createRun();
newRun.setText(" "+texts[n].trim());
if(texts.length>1 && n!=texts.length-1){
newRun.addBreak();
}
newRun.setText(runText);
newRun.setFontSize(size);
newRun.setFontFamily(fontFamily);
}
}else if(runText.indexOf("\n")!=-1){
String[] texts = runText.split("\n");
List<String> tmp = new ArrayList<>();
for (String text : texts) {
if(text!=null && text.length()!=0){
tmp.add(text.trim());
}
}
texts = tmp.toArray(new String[0]);
for (int n = 0; n < texts.length; n++) {
XWPFRun newRun = paragraph.createRun();
newRun.setText(" "+texts[n].trim());
if(texts.length>1 && n!=texts.length-1){
newRun.addBreak();
}
newRun.setFontSize(size);
newRun.setFontFamily(fontFamily);
}
}else{
//重新创建一个run用于设置文本
XWPFRun newrun = paragraph.insertNewRun(i);
newrun.setText(runText);
newrun.setFontSize(size);
newrun.setFontFamily(fontFamily);
}
}
}
}
}
}
}
/**
* 替换页眉里面的变量
* @param Header
* @param map
*/
public static void replaceHeader(XWPFHeader Header,Map<String,Object> map){
//获取表
List<XWPFTable> tableList = Header.getTables();
if(tableList!=null && tableList.size()>0){
for (int i = 0; i < tableList.size(); i++) {
XWPFTable table = tableList.get(i);
//获取行
List<XWPFTableRow> rows = table.getRows();
for (XWPFTableRow row : rows) {
//获取单元格
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
//获取单元格内容
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
// paragraph.setAlignment(ParagraphAlignment.LEFT);
replaceParagraph(paragraph,map);
}
}
}
}
}
else {
List<XWPFParagraph> paragraphs = Header.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
// paragraph.setAlignment(ParagraphAlignment.LEFT);
replaceParagraph(paragraph,map);
}
}
}
/**
* 替换页脚里面表格的变量
* @param Footer
* @param map
*/
public static void replaceFooter(XWPFFooter Footer, Map<String,Object> map){
//获取表
List<XWPFTable> tableList = Footer.getTables();
if(tableList!=null && tableList.size()>0){
for (int i = 0; i < tableList.size(); i++) {
XWPFTable table = tableList.get(i);
//获取行
List<XWPFTableRow> rows = table.getRows();
//获取单元格
for (XWPFTableRow row : rows) {
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
//获取段落
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
// paragraph.setAlignment(ParagraphAlignment.LEFT);
replaceParagraph(paragraph,map);
}
}
}
}
}
else {
List<XWPFParagraph> paragraphs = Footer.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
// paragraph.setAlignment(ParagraphAlignment.LEFT);
replaceParagraph(paragraph,map);
}
}
}
/**
* 替换表格里面的变量
* @param document
* @param map
*/
public static void replaceInTable(XWPFDocument document,Map<String,Object> map) throws Exception {
Iterator<XWPFTable> iterator = document.getTablesIterator();
while (iterator.hasNext()){
//获取表
XWPFTable table = iterator.next();
//获取行
List<XWPFTableRow> rows = table.getRows();
for (XWPFTableRow row : rows) {
//获取单元格
List<XWPFTableCell> cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
List<XWPFParagraph> paragraphs = cell.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
//paragraph.setAlignment(ParagraphAlignment.LEFT);
replaceParagraph(paragraph,map);
}
}
}
}
}
/**
* 导出docx
* @param templatePath
* @param outPath
* @param map
*/
public static boolean getDocx(String templatePath, String outPath,Map<String, Object> map){
XWPFDocument document = null;
try{
File file = new File(templatePath);
InputStream in = new FileInputStream(file);
document = new XWPFDocument(in);
//替换页眉变量
Iterator<XWPFHeader> headerIterator = document.getHeaderList().iterator();
while (headerIterator.hasNext()){
XWPFHeader header = headerIterator.next();
replaceHeader(header,map);
}
//替换页脚变量
Iterator<XWPFFooter> footerIterator = document.getFooterList().iterator();
while (footerIterator.hasNext()){
XWPFFooter footer = footerIterator.next();
replaceFooter(footer,map);
}
//替换表格里面的变量
replaceInTable(document,map);
// 如果文件夹不存在 则建立新文件夹
File dir= new File(outPath);
if (!dir.exists() == false) {
dir.mkdirs();
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
OutputStream out = new FileOutputStream(outPath);
document.write(bos);
out.write(bos.toByteArray());
bos.close();
out.close();
return true;
}
catch (Exception e){
e.printStackTrace();
return false;
} finally{
try
{
if ( document != null )
{
document.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
//测试
public static void main(String[] args) throws Exception{
HashMap map = new HashMap();
map.put("${title}", "人员信息表");
map.put("${name}", "张三");
map.put("${age}", "20岁");
map.put("${height}", "180cm");
map.put("${weight}", "70kg");
String templatePath = "D:\\1.docx";
String outPath = "D:\\2.docx";
getDocx(templatePath , outPath , map);
}