1 /**
2 * 复制单元格和样式
3 *
4 * @param targetRow 要复制的行
5 * @param sourceRow 被复制的行
6 * @param copyValue 是否复制值 true 复制, false 不复制
7 */
8 public static void createCellsAndCopyStyles(XWPFTableRow targetRow, XWPFTableRow sourceRow,boolean copyValue) {
9 targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
10 List<XWPFTableCell> tableCells = sourceRow.getTableCells();
11 if (CollectionUtil.isEmpty(tableCells)) {
12 return;
13 }
14 for (XWPFTableCell sourceCell : tableCells) {
15 XWPFTableCell newCell = targetRow.addNewTableCell();
16 if (copyValue){
17 newCell.setText(sourceCell.getText());
18 }
19 newCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
20 List sourceParagraphs = sourceCell.getParagraphs();
21 if (CollectionUtil.isEmpty(sourceParagraphs)) {
22 continue;
23 }
24 XWPFParagraph sourceParagraph = (XWPFParagraph) sourceParagraphs.get(0);
25 List targetParagraphs = newCell.getParagraphs();
26 XWPFParagraph targetParagraph = CollectionUtil.isEmpty(targetParagraphs) ? newCell.addParagraph() : (XWPFParagraph) targetParagraphs.get(0);
27 targetParagraph.getCTP().setPPr(sourceParagraph.getCTP().getPPr());
28 XWPFRun targetRun = targetParagraph.getRuns().isEmpty()
29 ? targetParagraph.createRun() : targetParagraph.getRuns().get(0);
30 List<XWPFRun> sourceRunList=sourceParagraph.getRuns();
31 if (CollectionUtil.isNotEmpty(sourceRunList)) {
32 XWPFRun sourceRun=sourceRunList.get(0);
33 //字体名称
34 targetRun.setFontFamily(sourceRun.getFontFamily());
35 //字体大小
36 targetRun.setFontSize(sourceRun.getFontSize());
37 //字体颜色
38 targetRun.setColor(sourceRun.getColor());
39 //字体加粗
40 targetRun.setBold(sourceRun.isBold());
41 //字体倾斜
42 targetRun.setItalic(sourceRun.isItalic());
43 }
44 }
45 }
46 /**
47 * 根据模板生成word文档
48 *
49 * @param inputStream InputStream
50 * @param textMap 需要替换的文本内容
51 * @param mapList 需要动态生成的内容 #none 表示空 #br表示换行
52 * @return
53 */
54 public static XWPFDocument changWord(InputStream inputStream , Map<String, Object> textMap, List<Object> mapList, int[] placeList) {
55 XWPFDocument document = null;
56 try {
57 //获取docx解析对象
58 document = new XWPFDocument(inputStream);
59
60 //解析替换文本段落对象
61 WorderToNewWordUtils.changeText(document, textMap);
62
63 //解析替换表格对象
64 WorderToNewWordUtils.changeTable(document, textMap, mapList, placeList);
65 } catch (IOException e) {
66 e.printStackTrace();
67 }
68 return document;
69 }
70 /**
71 * 根据模板生成word文档
72 *
73 * @param inputUrl 模板路径
74 * @param textMap 需要替换的文本内容
75 * @param mapList 需要动态生成的内容 #none 表示空 #br表示换行
76 * @return
77 */
78 public static XWPFDocument changWord(String inputUrl, Map<String, Object> textMap, List<Object> mapList, int[] placeList) {
79 XWPFDocument document = null;
80 try {
81 //获取docx解析对象
82 document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
83
84 //解析替换文本段落对象
85 WorderToNewWordUtils.changeText(document, textMap);
86
87 //解析替换表格对象
88 WorderToNewWordUtils.changeTable(document, textMap, mapList, placeList);
89 } catch (IOException e) {
90 e.printStackTrace();
91 }
92 return document;
93 }
94
95 /**
96 * 替换段落文本
97 *
98 * @param document docx解析对象
99 * @param textMap 需要替换的信息集合
100 */
101 public static void changeText(XWPFDocument document, Map<String, Object> textMap) {
102 //获取段落集合
103 List<XWPFParagraph> paragraphs = document.getParagraphs();
104
105 for (XWPFParagraph paragraph : paragraphs) {
106 //判断此段落时候需要进行替换
107 String text = paragraph.getText();
108 if (checkText(text)) {
109 List<XWPFRun> runs = paragraph.getRuns();
110 for (XWPFRun run : runs) {
111 //替换模板原来位置
112 Object ob = changeValue(run.toString(), textMap);
113 // System.out.println("段落:" + run.toString());
114 if (ob instanceof String) {
115 run.setText((String) ob, 0);
116 }
117 }
118 }
119 }
120
121 }
122
123 public static void changeTableText(XWPFDocument document, Map<String, Object> textMap){
124 List<XWPFTable> tables = document.getTables();
125 if (CollectionUtil.isNotEmpty(tables)){
126 for (XWPFTable table : tables){
127 //获取表格行数据
128 List<XWPFTableRow> rows = table.getRows();
129
130 }
131 }
132
133 }
134
135 /**
136 * 替换表格对象方法
137 *
138 * @param document docx解析对象
139 * @param textMap 需要替换的信息集合
140 * @param mapList 需要动态生成的内容
141 */
142 public static void changeTable(XWPFDocument document, Map<String, Object> textMap, List<Object> mapList, int[] placeList) {
143 //获取表格对象集合
144 List<XWPFTable> tables = document.getTables();
145
146 //循环所有需要进行替换的文本,进行替换
147 for (int i = 0; i < tables.size(); i++) {
148 XWPFTable table = tables.get(i);
149 if (checkText(table.getText())) {
150 List<XWPFTableRow> rows = table.getRows();
151 //遍历表格,并替换模板
152 eachTable(document, rows, textMap);
153 }
154 }
155
156 int index = 0;
157 //操作word中的表格
158 if (mapList != null) {
159 for (int i = 0; i < tables.size(); i++) {
160 //只处理行数大于等于2的表格,且不循环表头
161 XWPFTable table = tables.get(i);
162 if (placeList[index] == i) {
163 List<String[]> list = (List<String[]>) mapList.get(index);
164 //第二个表格使用daList,插入数据
165 if (null != list && 0 < list.size()) {
166 insertTable(table, null, list, 2);
167 List<Integer[]> indexList = startEnd(list);
168 for (int c = 0; c < indexList.size(); c++) {
169 //合并行
170 mergeCellVertically(table, 0, indexList.get(c)[0] + 1, indexList.get(c)[1] + 1);
171 }
172 }
173 index++;
174 }
175
176 }
177 }
178
179 }
180
181 /**
182 * 遍历表格
183 *
184 * @param rows 表格行对象
185 * @param textMap 需要替换的信息集合
186 */
187 public static void eachTable(XWPFDocument document, List<XWPFTableRow> rows, Map<String, Object> textMap) {
188 for (XWPFTableRow row : rows) {
189 List<XWPFTableCell> cells = row.getTableCells();
190 for (XWPFTableCell cell : cells) {
191 //判断单元格是否需要替换
192 if (checkText(cell.getText())) {
193 List<XWPFParagraph> paragraphs = cell.getParagraphs();
194 for (XWPFParagraph paragraph : paragraphs) {
195 List<XWPFRun> runs = paragraph.getRuns();
196 String x="";
197 for (XWPFRun run : runs) {
198
199 Object ob = changeValue(run, textMap);
200 if (ob instanceof String) {
201 if (((String) ob).indexOf("\n") > 0){
202 continue;
203 }
204 if (((String) ob).equalsIgnoreCase("#none")){
205 run.setText("",0);
206 }else if (((String) ob).indexOf("#br")!=-1){
207 String []obs=((String) ob).split("#br");
208 run.setText(obs[0],0);
209 for (int i= 1;i<obs.length;i++){
210 run.addBreak();
211 run.setText(obs[i],i);
212 }
213
214 }else {
215 run.setText((String) ob, 0);
216 }
217
218 } else if (ob instanceof Map) {
219
220 }// 下载头像
221 if (run.toString().contains("http")){
222 InputStream inputStream = null;
223 try {
224 URL url = new URL(run.toString());
225 inputStream = url.openStream();
226 run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG,"", Units.toEMU(100), Units.toEMU(110));
227 } catch (Exception e) {
228 e.printStackTrace();
229 } finally {
230 run.setText(null,0);
231 IoUtil.close(inputStream);
232 }
233 }
234
235 }
236
237
238 }
239 }
240 }
241 }
242 }
243
244 /**
245 * 为表格插入数据,行数不够添加新行
246 *
247 * @param table 需要插入数据的表格
248 * @param tableList 第四个表格的插入数据
249 * @param daList 第二个表格的插入数据
250 * @param type 表格类型:1-第一个表格 2-第二个表格 3-第三个表格 4-第四个表格
251 */
252 public static void insertTable(XWPFTable table, List<String> tableList, List<String[]> daList, Integer type) {
253 if (2 == type) {
254 //创建行和创建需要的列
255 for (int i = 1; i < daList.size(); i++) {
256 //添加一个新行
257 XWPFTableRow row = table.insertNewTableRow(1);
258 for (int k = 0; k < daList.get(0).length; k++) {
259 row.createCell();//根据String数组第一条数据的长度动态创建列
260 }
261 }
262
263 //创建行,根据需要插入的数据添加新行,不处理表头
264 for (int i = 0; i < daList.size(); i++) {
265 List<XWPFTableCell> cells = table.getRow(i + 1).getTableCells();
266 for (int j = 0; j < cells.size(); j++) {
267 XWPFTableCell cell02 = cells.get(j);
268 cell02.setText(daList.get(i)[j]);
269 }
270 }
271 } else if (4 == type) {
272 //插入表头下面第一行的数据
273 for (int i = 0; i < tableList.size(); i++) {
274 XWPFTableRow row = table.createRow();
275 List<XWPFTableCell> cells = row.getTableCells();
276 cells.get(0).setText(tableList.get(i));
277 }
278 }
279 }
280
281 /**
282 * 判断文本中时候包含$
283 *
284 * @param text 文本
285 * @return 包含返回true, 不包含返回false
286 */
287 public static boolean checkText(String text) {
288 boolean check = false;
289 if (text.indexOf("$") != -1) {
290 check = true;
291 }
292 return check;
293 }
294 /**
295 * 匹配传入信息集合与模板
296 *
297 * @param run 模板需要替换的区域
298 * @param textMap 传入信息集合
299 * @return 模板需要替换区域信息集合对应值
300 */
301 public static Object changeValue(XWPFRun run, Map<String, Object> textMap) {
302 String value = run.toString();
303 Set<Map.Entry<String, Object>> textSets = textMap.entrySet();
304 Object valu = value;
305
306 for (Map.Entry<String, Object> textSet : textSets) {
307 //匹配模板与替换值 格式${key}
308 String key = textSet.getKey();
309 if (value.indexOf(key) != -1) {
310 if(ObjectUtil.isNotEmpty(textSet.getValue())){
311 valu = value.replace(key, (String) textSet.getValue());}
312 else {
313 valu = value.replace(key, "暂无");
314 }
315 value=(String)valu;
316 }
317 }
318 if (value.indexOf("\n") > 0){
319 run.setText(null,0);
320 String[] split = value.split("\n");
321 for (int i = 0; i < split.length; i++) {
322 if ( 0 == i){
323 run.setText(split[i]);
324 }else{
325 run.addBreak();
326 run.setText(split[i]);
327 }
328 }
329 }
330
331 return valu;
332 }
333 /**
334 * 匹配传入信息集合与模板
335 *
336 * @param value 模板需要替换的区域
337 * @param textMap 传入信息集合
338 * @return 模板需要替换区域信息集合对应值
339 */
340 public static Object changeValue(String value, Map<String, Object> textMap) {
341 Set<Map.Entry<String, Object>> textSets = textMap.entrySet();
342 Object mesg ;
343 if (textMap.containsKey(value)) {
344 mesg = textMap.get(value);
345 } else {
346 mesg = "暂无";
347 }
348 return mesg;
349 }
350
351 /**
352 * 将输入流中的数据写入字节数组
353 *
354 * @param in
355 * @return
356 */
357 public static byte[] inputStream2ByteArray(InputStream in, boolean isClose) {
358 byte[] byteArray = null;
359 try {
360 int total = in.available();
361 byteArray = new byte[total];
362 in.read(byteArray);
363 } catch (IOException e) {
364 e.printStackTrace();
365 } finally {
366 if (isClose) {
367 try {
368 in.close();
369 } catch (Exception e2) {
370 System.out.println("关闭流失败");
371 }
372 }
373 }
374 return byteArray;
375 }
376
377 /**
378 * 合并行
379 *
380 * @param table
381 * @param col 需要合并的列
382 * @param fromRow 开始行
383 * @param toRow 结束行
384 */
385 public static void mergeCellVertically(XWPFTable table, int col, int fromRow, int toRow) {
386 for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
387 CTVMerge vmerge = CTVMerge.Factory.newInstance();
388 if (rowIndex == fromRow) {
389 vmerge.setVal(STMerge.RESTART);
390 } else {
391 vmerge.setVal(STMerge.CONTINUE);
392 }
393 XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
394 CTTcPr tcPr = cell.getCTTc().getTcPr();
395 if (tcPr != null) {
396 tcPr.setVMerge(vmerge);
397 } else {
398 tcPr = CTTcPr.Factory.newInstance();
399 tcPr.setVMerge(vmerge);
400 cell.getCTTc().setTcPr(tcPr);
401 }
402 }
403 }
404
405 /**
406 * 获取需要合并单元格的下标
407 *
408 * @return
409 */
410 public static List<Integer[]> startEnd(List<String[]> daList) {
411 List<Integer[]> indexList = new ArrayList<Integer[]>();
412 List<String> list = new ArrayList<String>();
413 for (int i = 0; i < daList.size(); i++) {
414 list.add(daList.get(i)[0]);
415 }
416 Map<Object, Integer> tm = new HashMap<Object, Integer>();
417 for (int i = 0; i < daList.size(); i++) {
418 if (!tm.containsKey(daList.get(i)[0])) {
419 tm.put(daList.get(i)[0], 1);
420 } else {
421 int count = tm.get(daList.get(i)[0]) + 1;
422 tm.put(daList.get(i)[0], count);
423 }
424 }
425 for (Map.Entry<Object, Integer> entry : tm.entrySet()) {
426 String key = entry.getKey().toString();
427 String value = entry.getValue().toString();
428 if (list.indexOf(key) != (-1)) {
429 Integer[] index = new Integer[2];
430 index[0] = list.indexOf(key);
431 index[1] = list.lastIndexOf(key);
432 indexList.add(index);
433 }
434 }
435 return indexList;
436 }