01.导入依赖
cn.afterturn
easypoi-base
3.2.0
cn.afterturn
easypoi-annotation
3.2.0
cn.afterturn
easypoi-web
3.2.0
org.apache.poi
poi
3.15
org.apache.poi
poi-ooxml-schemas
3.15
org.apache.poi
poi-ooxml
3.15
02. 工具类
/**
* @Author: SwordsMan 133-8660-9751
* @Date: 2020/4/10 14:30
* @Describe:
*/
public class WordUtils {
/**
* 生成word
*
* @param path
* @param params
* @param tableList
* @param fileName
* @param response
* @throws Exception
*/
public void getWord(String path, Map params, List> tableList, String fileName, HttpServletResponse response) throws Exception {
URL url = WordUtils.class.getClassLoader().getResource(path);
InputStream is = new FileInputStream(WordUtils.getResource(path));
CustomXWPFDocument doc = new CustomXWPFDocument(is);
this.replaceInPara(doc, params);//替换文本里面的变量
for (int i = 0; i < tableList.size(); i++) {//2 个
this.replaceInTable(doc, params, i, tableList.get(i));
}
//this.replaceInTable(doc, params, tableList); //替换表格里面的变量
OutputStream os = response.getOutputStream();
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
doc.write(os);
this.close(os);
this.close(is);
}
/**
* 获取路径
*
* @param relativePath
* @return
* @throws IOException
*/
public static String getResource(String relativePath) throws IOException {
String filePath = System.getProperty("user.dir") + File.separator + "config" + File.separator + relativePath;
File file = new File(filePath);
if (!file.exists()) {
URL url = WordUtils.class.getClassLoader().getResource(relativePath);
return url.getFile();
}
return file.getCanonicalPath();
}
/**
* 替换的变量
*
* @param doc
* @param params
*/
private void replaceInPara(CustomXWPFDocument doc, Map params) {
Iterator iterator = doc.getParagraphsIterator();
XWPFParagraph para;
while (iterator.hasNext()) {
para = iterator.next();
this.replaceInPara(para, params, doc);
}
}
/**
* 替换变量
*
* @param para
* @param params
* @param doc
*/
private void replaceInPara(XWPFParagraph para, Map params, CustomXWPFDocument doc) {
List runs;
Matcher matcher;
if (this.matcher(para.getParagraphText()).find()) {
runs = para.getRuns();
int start = -1;
int end = -1;
String str = "";
for (int i = 0; i < runs.size(); i++) {
XWPFRun run = runs.get(i);
String runText = run.toString();
if ('$' == runText.charAt(0) && '{' == runText.charAt(1)) {
start = i;
}
if ((start != -1)) {
str += runText;
}
if ('}' == runText.charAt(runText.length() - 1)) {
if (start != -1) {
end = i;
break;
}
}
}
for (int i = start; i <= end; i++) {
para.removeRun(i);
i--;
end--;
}
for (Map.Entry entry : params.entrySet()) {
String key = entry.getKey();
if (str.indexOf(key) != -1) {
Object value = entry.getValue();
if (value instanceof String) {
str = str.replace(key, value.toString());
para.createRun().setText(str, 0);
break;
} else if (value instanceof Map) {
str = str.replace(key, "");
Map pic = (Map) value;
int width = Integer.parseInt(pic.get("width").toString());
int height = Integer.parseInt(pic.get("height").toString());
int picType = getPictureType(pic.get("type").toString());
byte[] byteArray = (byte[]) pic.get("content");
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);
try {
//int ind = doc.addPicture(byteInputStream,picType);
//doc.createPicture(ind, width , height,para);
doc.addPictureData(byteInputStream, picType);
doc.createPicture(doc.getAllPictures().size() - 1, width, height, para);
para.createRun().setText(str, 0);
break;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
/**
* 添加新行
*
* @param table
* @param tableList
*/
private static void insertTable(XWPFTable table, List tableList) {
//创建行,根据需要插入的数据添加新行,不处理表头
for (int i = 0; i < tableList.size(); i++) {
XWPFTableRow row = table.createRow();
}
int length = table.getRows().size();//行数
for (int i = 1; i < length - 1; i++) {//便利要添加的行
XWPFTableRow newRow = table.getRow(i);
List tableCells = newRow.getTableCells();//单元格
for (int j = 0; j < tableCells.size(); j++) {
XWPFTableCell xwpfTableCell = tableCells.get(j);//获取到了具体的单元格
String s = tableList.get(i - 1)[j];
xwpfTableCell.setText(s);
}
}
}
/**
* 替换表格里面的变量
*
* @param doc
* @param params
* @param tableList
*/
private void replaceInTable(CustomXWPFDocument doc, Map params, int pos, List tableList) {
List tables = doc.getTables();
List rows;
List cells;
List paras;
XWPFTable table = tables.get(pos);
if (table.getRows().size() > 1) {
//判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
if (this.matcher(table.getText()).find()) {
rows = table.getRows();
for (XWPFTableRow row : rows) {
cells = row.getTableCells();
for (XWPFTableCell cell : cells) {
paras = cell.getParagraphs();
for (XWPFParagraph para : paras) {
this.replaceInPara(para, params, doc);
}
}
}
} else {
insertTable(table, tableList); //插入数据
}
}
}
/**
* 匹配数据
* @param str
* @return
*/
private Matcher matcher(String str) {
Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
return matcher;
}
/**
* 获取图片
* @param picType
* @return
*/
private static int getPictureType(String picType) {
int res = CustomXWPFDocument.PICTURE_TYPE_PICT;
if (picType != null) {
if (picType.equalsIgnoreCase("png")) {
res = CustomXWPFDocument.PICTURE_TYPE_PNG;
} else if (picType.equalsIgnoreCase("dib")) {
res = CustomXWPFDocument.PICTURE_TYPE_DIB;
} else if (picType.equalsIgnoreCase("emf")) {
res = CustomXWPFDocument.PICTURE_TYPE_EMF;
} else if (picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")) {
res = CustomXWPFDocument.PICTURE_TYPE_JPEG;
} else if (picType.equalsIgnoreCase("wmf")) {
res = CustomXWPFDocument.PICTURE_TYPE_WMF;
}
}
return res;
}
/**
* 流转化
* @param in
* @param isClose
* @return
*/
public static byte[] inputStream2ByteArray(InputStream in, boolean isClose) {
byte[] byteArray = null;
try {
int total = in.available();
byteArray = new byte[total];
in.read(byteArray);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isClose) {
try {
in.close();
} catch (Exception e2) {
e2.getStackTrace();
}
}
}
return byteArray;
}
/**
* 关闭输入流
* @param is
*/
private void close(InputStream is) {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 关闭输出流流
* @param os
*/
private void close(OutputStream os) {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
03. word模板
04. controller调用
@RestController
@RequestMapping("test")
public class WordUtilsTest {
@RequestMapping("te")
public void test(HttpServletResponse response) throws Exception {
WordUtils wordUtils = new WordUtils();
Map reportMap = new HashMap<>();
//文本信息要放到map中
reportMap.put("name","多情剑客多情剑");
reportMap.put("age","233");
//多个动态表格数据要放到一个大list中,每个表格的数据又被装在一个list里面,每行数据是一个字符串数组
//实际开发中可以将数据遍历插入到字符串数组中
List> testList = new ArrayList<>();
List subList1 = new ArrayList<>();
subList1.add(new String[] {"1","2","3","re","hjfkd"});
subList1.add(new String[] {"1","2","3","re","hjfkd"});
subList1.add(new String[] {"1","2","3","re","hjfkd"});
subList1.add(new String[] {"1","2","3","re","hjfkd"});
List subList2 = new ArrayList<>();
subList2.add(new String[] {"fk","gfd","df","dfg","gdf","gdf","gfdsd"});
subList2.add(new String[] {"fk","gfd","df","dfg","gdf","gdf","gfdsd"});
subList2.add(new String[] {"fk","gfd","df","dfg","gdf","gdf","gfdsd"});
testList.add(subList1);
testList.add(subList2);
String path = "word/www.docx";//模板位置
String fileName= new String("测试文档.docx".getBytes("UTF-8"),"iso-8859-1");
// 04 导出报表
wordUtils.getWord(path,reportMap,testList,fileName,response);
}
}
05. 导出