匯出Word工具類(根據資料動態生成並跨列)
阿新 • • 發佈:2021-07-13
package com.ksource.modules.common; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import net.sf.json.util.JSONTokener; import org.apache.poi.xwpf.usermodel.*; import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; /** * @author dxy * */ @Component public class ExportWordUtil { public void createTable(String name, JSONArray json, HttpServletRequest request, HttpServletResponse response) throws Exception { XWPFDocument xdoc = new XWPFDocument(); XWPFParagraph xp = xdoc.createParagraph(); xp.setSpacingBefore(0); XWPFRun r = xp.createRun(); r.setText(name+"查詢資訊"); r.setFontFamily("宋體"); r.setFontSize(18); r.setTextPosition(10); r.setBold(true); r.addBreak(); // 換行 xp.setAlignment(ParagraphAlignment.CENTER); int sign = 0; for(int i = 0; i < json.size(); i++){ JSONObject jsonObject = JSONObject.fromObject(json.get(i).toString()); if ("1".equals(jsonObject.get("flag").toString())){ sign = ++sign; xdoc.createParagraph(); XWPFParagraph xp1 = xdoc.createParagraph(); XWPFRun r1 = xp1.createRun(); r1.setText((sign) +"."+ jsonObject.get("resourceName").toString()); r1.setFontFamily("宋體"); r1.setFontSize(16); r1.setBold(true); r1.setTextPosition(10); //r.addBreak(); // 換行 xp1.setAlignment(ParagraphAlignment.LEFT); if (jsonObject.get("result") != null){ int index = 0; JSONObject resultJsonObject = JSONObject.fromObject(jsonObject.get("result").toString()); for(Object key : resultJsonObject.keySet()){ String flag = parseJsonFormat(key.toString(),resultJsonObject.get(key).toString()); System.out.println(resultJsonObject.get(key).toString()); System.out.println(flag); writeDoc(xdoc,(sign)+"."+(++index),key.toString(),resultJsonObject.get(key).toString(),flag); } } } } downloadWord(xdoc,request,response); } private void writeDoc(XWPFDocument xdoc, String index, String key, String value, String flag){ xdoc.createParagraph(); XWPFParagraph xp = xdoc.createParagraph(); XWPFRun r = xp.createRun(); r.setText(index +"."+ key); r.setFontFamily("宋體"); r.setFontSize(14); r.setBold(true); r.setTextPosition(10); //r.addBreak(); // 換行 xp.setAlignment(ParagraphAlignment.LEFT); if("1".equals(flag)){ getDetail(xdoc,value); }else if("2".equals(flag)){ getList(xdoc,value); }else if("3".equals(flag)){ getDetailList(xdoc,value); } } /** * 獲取詳情 * @param xdoc * @param value */ public void getDetail(XWPFDocument xdoc, String value){ xdoc.createParagraph(); int keyCount = 0; JSONObject valueJsonObject = JSONObject.fromObject(value); List list = new ArrayList(); for(Object k : valueJsonObject.keySet()){ ++keyCount; list.add(k.toString()); list.add(valueJsonObject.get(k).toString()); } int fromCellIndex = keyCount*2 % 6; Integer row_total_count = (keyCount*2%6 == 0) ? keyCount*2/6 : (keyCount*2/6 + 1); Integer col_total_count = 6; // 表格最多的列數 if(keyCount * 2 < 6){ col_total_count = keyCount * 2; } XWPFTable xTable = xdoc.createTable(); CTTbl ttbl = xTable.getCTTbl(); CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr(); CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW(); tblWidth.setW(new BigInteger("9072")); tblWidth.setType(STTblWidth.DXA); for (int i = 0; i < row_total_count; i++) { XWPFTableRow row = xTable.insertNewTableRow(i); row.setHeight(450); int t = i*col_total_count; for (int j = 0; j < col_total_count; j++) { XWPFTableCell cell = row.createCell(); XWPFParagraph p = cell.addParagraph(); p.setAlignment(ParagraphAlignment.CENTER); p.setSpacingBefore(100); XWPFRun xRun = p.createRun(); xRun.setFontSize(9); if ((j+t) < list.size()){ if(j % 2 == 0){ xRun.setBold(true);//是否粗體 cell.setColor("f0f7ff"); } if(!"".equals(list.get(j+t).toString())){ xRun.setText(list.get(j+t).toString()); }else{ xRun.setText("暫無"); } }else if(i == row_total_count - 1 && j == col_total_count - 1){ mergeCellsHorizontal(xTable,row_total_count-1,col_total_count,fromCellIndex-1,col_total_count-1); } } } xTable.removeRow(row_total_count); } /** * 獲取列表 * @param xdoc * @param value */ public void getList(XWPFDocument xdoc, String value){ JSONArray valueJsonArray = JSONArray.fromObject(value); for (int i = 0; i < valueJsonArray.size(); i++){ getDetail(xdoc,valueJsonArray.get(i).toString()); } } /** * 獲取詳情和列表 * @param xdoc * @param value */ public void getDetailList(XWPFDocument xdoc, String value){ JSONObject valueJsonObject = JSONObject.fromObject(value); for(Object k : valueJsonObject.keySet()){ String flag = parseJsonFormat(k.toString(),valueJsonObject.get(k).toString()); if("1".equals(flag)){ getDetail(xdoc,valueJsonObject.get(k).toString()); }else if("2".equals(flag)){ getList(xdoc,valueJsonObject.get(k).toString()); } } } /** * 判斷json格式 * @param key * @param value * @return */ public String parseJsonFormat(String key, String value){ //當flag=1時json格式為詳情,當flag=2時json格式為列表,當flag=3時json格式為詳情+列表 String flag = ""; Object json = new JSONTokener(value).nextValue(); if(json instanceof JSONObject){ JSONObject jsonObject = (JSONObject)json; for(Object k : jsonObject.keySet()){ boolean isJSON = isJSON(jsonObject.get(k).toString()); if(isJSON){ flag = "3"; break; }else{ flag = "1"; } } }else if (json instanceof JSONArray){ JSONArray jsonArray = (JSONArray)json; flag = "2"; } return flag; } /** * 判斷是否為json * @param str * @return */ public boolean isJSON(String str) { boolean result = false; try { Object obj = JSONObject.fromObject(str); result = true; } catch (Exception e) { result=false; } return result; } /** * 設定表頭內容 * @param cell * @param text * @param bgcolor * @param width */ private static void setCellText(XWPFDocument xdoc, XWPFTableCell cell, String text, String bgcolor, int width) { CTTc cttc = cell.getCTTc(); CTTcPr cellPr = cttc.addNewTcPr(); cellPr.addNewTcW().setW(BigInteger.valueOf(width)); XWPFParagraph paragraph = cell.getParagraphs().get(0); paragraph.setAlignment(ParagraphAlignment.CENTER); //設定表頭單元格居中 XWPFRun run = paragraph.createRun(); run.setFontFamily("仿宋_GB2312"); run.setFontSize(16); //設定表頭單元格字號 //run.setBold(true); //設定表頭單元格加粗 run.setText(text); } /** * 設定列寬 * * @param index * @return */ private static int getCellWidth(int index) { int cwidth = 1000; if (index == 0) { cwidth = 1000; } else if (index == 1) { cwidth = 2100; } else if (index == 2) { cwidth = 3200; } else if (index == 3) { cwidth = 2100; } return cwidth; } /** * 跨列合併 * @param table * @param row 所合併的行 * @param fromCell 起始列 * @param toCell 終止列 */ public void mergeCellsHorizontal(XWPFTable table, int row, int colNum, int fromCell, int toCell) { table.getRow(row).getCell(fromCell).getCTTc().addNewTcPr().addNewTcW() .setW(BigInteger.valueOf((9072 / colNum) * (toCell - fromCell + 1))); for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) { XWPFTableCell cell = table.getRow(row).getCell(cellIndex); if ( cellIndex == fromCell ) { // The first merged cell is set with RESTART merge value cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART); } else { // Cells which join (merge) the first one, are set with CONTINUE cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE); } } } /** * 跨行合併 * * @param table * @param col * @param fromRow * @param toRow */ public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) { for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) { XWPFTableCell cell = table.getRow(rowIndex).getCell(col); if (rowIndex == fromRow) { // The first merged cell is set with RESTART merge value cell.getCTTc().addNewTcPr().addNewVMerge() .setVal(STMerge.RESTART); } else { // Cells which join (merge) the first one, are set with CONTINUE cell.getCTTc().addNewTcPr().addNewVMerge() .setVal(STMerge.CONTINUE); } } } /** * 將檔案轉換成byte陣列 * @return */ public byte[] fileToByte(File file){ byte[] buffer = null; try { FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int n; while ((n = fis.read(b)) != -1) { bos.write(b, 0, n); } fis.close(); bos.close(); buffer = bos.toByteArray(); }catch (FileNotFoundException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } return buffer; } /** * 下載 * @param xdoc * @param request * @param response * @throws Exception */ public static void downloadWord(XWPFDocument xdoc, HttpServletRequest request, HttpServletResponse response) throws Exception { response.setCharacterEncoding("UTF-8"); //response.setHeader("Content-disposition", "attachment;filename=" + fileName); response.setContentType("application/force-download");// 設定強制下載不開啟 response.setHeader("Content-disposition", "attachment"); //重新整理緩衝 response.flushBuffer(); OutputStream ouputStream = response.getOutputStream(); //將word寫入到response的輸出流中,供頁面下載該Excel檔案 xdoc.write(ouputStream); ouputStream.flush(); ouputStream.close(); } }