1 package com.bocsh.base.util;2
3 import java.io.ByteArrayOutputStream;4 import java.io.FileInputStream;5 import java.io.IOException;6 import java.util.List;7 import java.util.Map;8 import java.util.Map.Entry;9 import java.util.Set;10
11
12 //import org.apache.poi.POIXMLDocument;
13 import org.apache.poi.xwpf.usermodel.*;14
15 /**16 * 通过word模板生成新的word工具类17 *18 * @author zhiheng19 *20 *21 * XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档22 * XWPFParagraph代表文档、表格、标题等种的段落,由多个XWPFRun组成23 * XWPFRun代表具有同样风格的一段文本24 * XWPFTable代表一个表格25 * XWPFTableRow代表表格的一行26 * XWPFTableCell代表表格的一个单元格27 * XWPFChar 表示.docx文件中的图表28 * XWPFHyperlink 表示超链接29 * XWPFPicture 代表图片30 *31 *32 *33 */
34 public classWorderToNewWordUtils {35
36 /**37 * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入38 * @param inputUrl 模板存放地址39 * @param textMap 需要替换的信息集合40 * @param excelDataBytes 生成了新的数据流 word格式, 存放容器41 * @return 成功返回true,失败返回false42 */
43 public staticboolean changWord(String inputUrl,44 Map textMap, MapexcelDataBytes) {45
46 //模板转换默认成功
47 boolean changeFlag = true;48 ByteArrayOutputStream writeToBytes = null;49 try{50 //获取docx解析对象
51 XWPFDocument document = new XWPFDocument(newFileInputStream(inputUrl));52 //解析替换文本段落对象
53 WorderToNewWordUtils.changeText(document, textMap);54 //解析替换表格对象
55 WorderToNewWordUtils.changeTable(document, textMap);56
57 //生成了新的数据流 word 格式
58 writeToBytes = newByteArrayOutputStream();59 document.write(writeToBytes);60 excelDataBytes.put(textMap.get("year") + textMap.get("month"), writeToBytes.toByteArray());61
62 } catch(IOException e) {63 e.printStackTrace();64 changeFlag = false;65 }finally{66 try{67 if(writeToBytes!=null)68 writeToBytes.close();69 } catch(IOException e) {70 e.printStackTrace();71 }72 }73
74 returnchangeFlag;75
76 }77
78
79 /**80 * 替换段落文本81 * @param document docx解析对象82 * @param textMap 需要替换的信息集合83 */
84 public static void changeText(XWPFDocument document, MaptextMap){85 //获取段落集合
86 List paragraphs =document.getParagraphs();87
88 for(XWPFParagraph paragraph : paragraphs) {89 //判断此段落时候需要进行替换
90 String text =paragraph.getText();91 if(checkText(text)){92 List runs =paragraph.getRuns();93 for(XWPFRun run : runs) {94 //替换模板原来位置
95 run.setText(changeValue(run.toString(), textMap),0);96 }97 }98 }99
100 }101
102 /**103 * 替换表格对象方法104 * @param document docx解析对象105 * @param textMap 需要替换的信息集合106 */
107 private static void changeTable(XWPFDocument document, MaptextMap){108 //获取表格对象集合
109 List tables =document.getTables();110 for (int i = 0; i < tables.size(); i++) {111 //只处理行数大于等于2的表格,且不循环表头
112 XWPFTable table = tables.get(i);113 if(table.getRows().size()>1){114 //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
115 if(checkText(table.getText())){116 List rows =table.getRows();117 //遍历表格,并替换模板
118 eachTable(rows, textMap);119 }120 }121 }122
123
124 }125
126
127 /**128 * 遍历表格129 * @param rows 表格行对象130 * @param textMap 需要替换的信息集合131 */
132 private static void eachTable(List rows ,MaptextMap){133 for(XWPFTableRow row : rows) {134 List cells =row.getTableCells();135 for(XWPFTableCell cell : cells) {136 //判断单元格是否需要替换
137 if(checkText(cell.getText())){138 List paragraphs =cell.getParagraphs();139 for(XWPFParagraph paragraph : paragraphs) {140 List runs =paragraph.getRuns();141 for(XWPFRun run : runs) {142 run.setText(changeValue(run.toString(), textMap),0);143 }144 }145 }146 }147 }148 }149
150
151 /**152 * 判断文本中时候包含$153 * @param text 文本154 * @return 包含返回true,不包含返回false155 */
156 private staticboolean checkText(String text){157 boolean check = false;158 if(text.indexOf("$")!= -1){159 check = true;160 }161 returncheck;162
163 }164
165 /**166 * 匹配传入信息集合与模板167 * @param value 模板需要替换的区域168 * @param textMap 传入信息集合169 * @return 模板需要替换区域信息集合对应值170 */
171 private static String changeValue(String value, MaptextMap){172 Set> textSets =textMap.entrySet();173 for (EntrytextSet : textSets) {174 //匹配模板与替换值 格式${key}
175 String key = "${"+textSet.getKey()+"}";176 if(value.indexOf(key)!= -1){177 value =textSet.getValue();178 }179 }180 //模板未匹配到区域替换为空
181 if(checkText(value)){182 value = "0";183 }184 returnvalue;185 }186
187
188 }