java word工具类

  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     }
Java word 的工具类

 

posted @ 2024-02-29 11:02  烟雨蒙尘  阅读(38)  评论(0编辑  收藏  举报