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 }