Przeglądaj źródła

导出工具类-支持表头合并

ZHGYL_GKPT 5 lat temu
rodzic
commit
6e5cb7bc38

+ 179 - 19
src/main/java/com/minpay/common/util/ExportUtils.java

@@ -1,16 +1,27 @@
 package com.minpay.common.util;
 
+import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.xssf.usermodel.*;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 /**
  *
  */
 public class ExportUtils {
     public final static String COLUMNS_SEPARATOR = "#";//分割符
+    //03Excel:单个sheet可以保存:行(65536)*列(256)=16777216个数据。
+    //07Excel:单个sheet可以保存:行(1048576)*列(16384)=17179869184个数据。
+    public final static int EXCEL_DATA_SIZE = 65000;
+    private static XSSFWorkbook xwb ;
+    private static XSSFSheet sheet;
+    private static XSSFRow row;
+    private static XSSFCell cell ;
+    private static XSSFCellStyle cellStyle;
+    private static XSSFFont fontStyle;
     /**
      * 描述列样式
      * @param wb
@@ -26,13 +37,13 @@ public class ExportUtils {
         style.setBorderRight(XSSFCellStyle.BORDER_THIN);
         style.setBorderTop(XSSFCellStyle.BORDER_THIN);
         style.setAlignment(XSSFCellStyle.ALIGN_LEFT);
+        style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
         // 生成一个字体
         XSSFFont font = wb.createFont();
         font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
         font.setFontName("宋体");
         font.setColor(new XSSFColor(java.awt.Color.RED));
         font.setFontHeightInPoints((short) 12);
-        // 把字体应用到当前的样式
         style.setFont(font);
         return style;
     }
@@ -53,13 +64,13 @@ public class ExportUtils {
         style.setBorderRight(XSSFCellStyle.BORDER_THIN);
         style.setBorderTop(XSSFCellStyle.BORDER_THIN);
         style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
+//        style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
         // 生成一个字体
         XSSFFont font = wb.createFont();
         font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
         font.setFontName("宋体");
         font.setColor(new XSSFColor(java.awt.Color.BLACK));
         font.setFontHeightInPoints((short) 11);
-        // 把字体应用到当前的样式
         style.setFont(font);
         return style;
     }
@@ -71,23 +82,27 @@ public class ExportUtils {
      */
     public static XSSFCellStyle getTextCellStyle(XSSFWorkbook wb) {
         // 生成并设置另一个样式
-        XSSFCellStyle style2 = wb.createCellStyle();
-        style2.setFillForegroundColor(new XSSFColor(java.awt.Color.WHITE));
-        style2.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
-        style2.setBorderBottom(XSSFCellStyle.BORDER_THIN);
-        style2.setBorderLeft(XSSFCellStyle.BORDER_THIN);
-        style2.setBorderRight(XSSFCellStyle.BORDER_THIN);
-        style2.setBorderTop(XSSFCellStyle.BORDER_THIN);
-        style2.setAlignment(XSSFCellStyle.ALIGN_CENTER);
-        style2.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
-        // 生成另一个字体
+        XSSFCellStyle style = wb.createCellStyle();
+        style.setFillForegroundColor(new XSSFColor(java.awt.Color.WHITE));
+        style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
+        style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
+        style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
+        style.setBorderRight(XSSFCellStyle.BORDER_THIN);
+        style.setBorderTop(XSSFCellStyle.BORDER_THIN);
+        style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
+        style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
         XSSFFont font2 = wb.createFont();
         font2.setBoldweight(XSSFFont.BOLDWEIGHT_NORMAL);
-        // 把字体应用到当前的样式
-        style2.setFont(font2);
-        return style2;
+        style.setFont(font2);
+        return style;
     }
 
+    /**
+     *  重组表头数据
+     * @param titleArray
+     * @param manyTitle
+     * @return
+     */
     public static String[] autocomplete(String[] titleArray, int manyTitle) {
         for(int i = 0; i< titleArray.length; i++) {
             titleArray[i] = completeStr(titleArray[i], manyTitle - titleArray[i].split(COLUMNS_SEPARATOR).length);
@@ -101,22 +116,158 @@ public class ExportUtils {
         col = col.split(COLUMNS_SEPARATOR)[0] + COLUMNS_SEPARATOR + col;
         return completeStr(col, --count);
     }
+    /**
+     * 创建sheet
+     * @param wb 工作簿
+     * @param sheetIndex sheet页下标
+     * @param sheetName sheet页名字
+     * @param titleArray 标题数组
+     * @param fieldArray 字段数组
+     * @param descStr
+     * @param list
+     * @param map
+     * @return
+     */
+    public static int XlzgzCreateSheet(XSSFWorkbook wb, int sheetIndex, String sheetName, String[] titleArray, String[] fieldArray,
+                                       String descStr, List<Map<String, String>> list, Map<String, String> map){
+        xwb = wb;
+        //样式
+        XSSFCellStyle textCellStyle = getTextCellStyle(xwb);
+        XSSFCellStyle titleCellStyle = getTitleCellStyle(xwb);
+        XSSFCellStyle descCellStyle= getDescCellStyle(xwb);
+        //计算
+        int datalist = 0;
+        int rowLock = 0;
+        if(list != null){
+            datalist  = list.size();
+        }
+        int avg = datalist/EXCEL_DATA_SIZE;
+        int sy = datalist%EXCEL_DATA_SIZE;
+        int favg = avg ;
+        if(sy==0&&avg!=0){
 
+        } else{
+            avg+=1;
+        }
+        //每页放EXCEL_2003_DATA_SIZE条数据
+        for (int ii = 0; ii < avg; ii++) {
+            String name = "";
+            if((favg==1 && sy==0)||(favg==0)){
+                name = sheetName ;
+            }else{
+                name = sheetName+"-sheet"+(ii+1) ;
+            }
+            sheet = wb.createSheet(name);
+            int rowIndex = 0;//当前行号
+            String title = StringUtil.ObjectToString(map.get("title"));
+            if(!"".equals(title)){//标题行
+                row = sheet.createRow((int) rowIndex);// 行数从0开始
+                row.setHeightInPoints(30);//设置行的高度
+                XSSFCell celldesc = row.createCell(0);
+                sheet.addMergedRegion(new CellRangeAddress(0,0,0,titleArray.length - 1));//合并单元格
+                celldesc.setCellValue(StringUtil.ObjectToString(title));
+                celldesc.setCellStyle(descCellStyle);
+                rowIndex ++;
+            }
+            if(!"".equals(descStr)){//描述行
+                //添加描述行
+                row = sheet.createRow((int) rowIndex);// 行数从0开始
+                row.setHeightInPoints(30);//设置行的高度
+                XSSFCell celldesc = row.createCell(0);
+                sheet.addMergedRegion(new CellRangeAddress(0,0,0,titleArray.length - 1));//合并单元格
+                celldesc.setCellValue(StringUtil.ObjectToString(descStr));
+                celldesc.setCellStyle(descCellStyle);
+                rowIndex++;
+            }
+            int manyTitle = 1;// 表头默认一行
+            if(titleArray.length > 0){//标题行
+                if (titleArray != null && titleArray.length > 0){
+                    for (int i = 0; i < titleArray.length; i++) {
+                        for (String col : titleArray) {
+                            String[] colTitles = col.split(ExportUtils.COLUMNS_SEPARATOR);
+                            manyTitle = Math.max(manyTitle,colTitles.length);
+                        }
+                    }
+                }
+                //重组表头
+                titleArray = ExportUtils.autocomplete(titleArray, manyTitle);
+                for (int j = 0; j < manyTitle; j++) {
+                    row = sheet.createRow((int) rowIndex);
+                    //  表头数据填充
+                    for(int i = 0; i < titleArray.length; i++) {
+                        cell = row.createCell(i );// 0号位被序号占用,所以需+1
+                        cell.setCellValue(titleArray[i].split("#")[j]);
+                        cell.setCellStyle(titleCellStyle);
+                        sheet.setColumnWidth(i, 30 * 256);
+                    }
+                    rowIndex ++;
+                }
+            }
+            rowLock = rowIndex;
+            sheet.createFreezePane(0, rowLock, 0, 0);
+            int rowLength		= 0;	//导出excel的总行数
+            if(ii < favg){
+                rowLength = EXCEL_DATA_SIZE;	//导出excel的总行数
+            }else{
+                rowLength = sy;	//导出excel的总行数
+            }
+            //合并表头
+            ExportUtils.titleMerge(sheet, rowIndex - manyTitle, titleArray, manyTitle);
+            //数据列
+            for (int i = 0; i < rowLength; i++) {
+                //创建行
+                row = sheet.createRow((int) rowIndex);
+                Map<String,String> temp = list.get( ii * EXCEL_DATA_SIZE + i);
+                for (int j = 0; j < fieldArray.length; j++) {
+                    cell = row.createCell(j);
+                    cell.setCellValue(StringUtil.ObjectToString(temp.get(fieldArray[j])));
+                    cell.setCellStyle(textCellStyle);
+                }
+                rowIndex ++;
+            }
+        }
+        return 0;
+    }
     /**
      * 表头数据合并
      * @param sheet
-     * @param coltitleIndex 列数
-     * @param colTitles 标题行
-     * @param num 行索引
+     * @param coltitleIndex 表头起始行
+     * @param colTitles 标题
+     * @param num 表头占几
      */
     public static void titleMerge(XSSFSheet sheet, int coltitleIndex, String[] colTitles, int num) {
+        List<int[]> melist = new ArrayList<>();
         for(int i = 0; i < num; i++) {
             String preVal = "";
             int columnIndex = 0;
             for(int j = 0; j < colTitles.length; j++) {
                 columnIndex++;
                 preVal = colTitles[j].split(COLUMNS_SEPARATOR)[i];
-                String columnVal = colTitles[j + 1].split(COLUMNS_SEPARATOR)[i];
+                String columnVal = "";
+                try {
+                    columnVal = colTitles[j + 1].split(COLUMNS_SEPARATOR)[i];
+                } catch (Exception e1) {
+                    List<Integer> list = new ArrayList<Integer>();
+                    for(int m = j - columnIndex + 1; m <= j; m++) {
+                        int bottom = 0;
+                        for(int k = i + 1; k <= num; k++) {
+                            String nextRowVal = "";
+                            try {
+                                nextRowVal = colTitles[m].split(COLUMNS_SEPARATOR)[k];
+                            } catch (Exception e) {
+                                list.add(bottom);
+                            }
+                            if(!"".equals(nextRowVal) && !preVal.equals(nextRowVal)) {
+                                list.add(bottom);
+                                break;
+                            }
+                            bottom++;
+                        }
+                    }
+                    Collections.sort(list);    //从小到大
+                    melist.add(new int[]{j  - columnIndex + 1,coltitleIndex + i, j, coltitleIndex + i + list.get(0)});
+                    columnIndex = 0;
+                }
                 if(!"".equals(columnVal) && !preVal.equals(columnVal)) {
                     List<Integer> list = new ArrayList<Integer>();
                     for(int m = j - columnIndex + 1; m <= j; m++) {
@@ -136,10 +287,19 @@ public class ExportUtils {
                         }
                     }
                     Collections.sort(list);    //从小到大
+                    melist.add(new int[]{j  - columnIndex + 1,coltitleIndex + i, j, coltitleIndex + i + list.get(0)});
                     columnIndex = 0;
                 }
                 preVal = columnVal;
             }
         }
+        if ( melist!= null &&  melist.size() > 0 ){
+            for (int i = 0; i < melist.size(); i++) {
+                int[] mergeCell = melist.get(i);
+                //合并单元格
+                sheet.addMergedRegion(new CellRangeAddress(mergeCell[1],mergeCell[3],mergeCell[0],mergeCell[2]));//合并单元格
+
+            }
+        }
     }
 }

+ 46 - 80
src/main/java/com/minpay/reportManage/action/XlgzzReportAction.java

@@ -247,11 +247,21 @@ public class XlgzzReportAction implements IMINAction {
         OutputStream out = null;
         out = response.getOutputStream();
         XSSFWorkbook wb = export(response, fileName, resMap);
-        if(wb != null){
-            wb.write(out);
+        try {
+            if(wb != null){
+                wb.write(out);
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }finally {
+            if(wb != null){
+
+            }
+            if(out != null){
+                out.flush();
+                out.close();
+            }
         }
-        out.flush();
-        out.close();
         return res;
     }
     public <T> XSSFWorkbook export(HttpServletResponse response, String fileName, Map<String, Object> map) throws Exception {
@@ -269,101 +279,57 @@ public class XlgzzReportAction implements IMINAction {
         Map<String,Object> temp = (Map<String, Object>) map.get("resList");
         List<String> tempList = (List<String>) temp.get("descStr");
         StringBuffer descxl = new StringBuffer();
-        descxl.append(tempList.get(0))
-                .append("/r/n")
-                .append(tempList.get(1));
+        descxl
+                .append("  ")
+                .append(tempList.get(0))
+                .append("\r\n")
+                .append("  ")
+                .append(tempList.get(1))
+                .append("\n")
+                .append("  ")
+                .append("注:线路负载率持续1小时在70%-100%为重载,持续1小时在100%以上为过载。");
         List<Map<String,String>> dataList = (List<Map<String, String>>) temp.get("result");
+//        for (int i = 0; i < 1000000; i++) {
+//            dataList.add(dataList.get(0));
+//        }
         int index = 0;
-        index = this.XlzgzCreateSheet(wb,index,"线路重载明细",titleArray,fieldArray,descxl.toString(),dataList,new HashMap<String,String>());
+        index = ExportUtils.XlzgzCreateSheet(wb,index,"线路重载明细",titleArray,fieldArray,descxl.toString(),dataList,new HashMap<String,String>());
 
         //******************************************线路过载明细******************************************//
         titleArray[3] = "过载时长(h)";
         List<Map<String,String>> dataList2 = (List<Map<String, String>>) temp.get("result2");
-        index = this.XlzgzCreateSheet(wb,index,"线路过载明细",titleArray,fieldArray,"",dataList2,new HashMap<String,String>());
+        index = ExportUtils.XlzgzCreateSheet(wb,index,"线路过载明细",titleArray,fieldArray,"",dataList2,new HashMap<String,String>());
 
-        //******************************************公变载明细******************************************//
+        //******************************************公变载明细******************************************//
         String[] titleArray2 = new String[]{"单位","供电所","公变名称","重载时长(h)","平均负载率(%)","原因","解决措施"};
         String[] fieldArray2 = new String[]{"DFD9_UNIT","DFD9_BZMC","DFD9_GBMC","DFD9_ZZSC","avg","DFD9_JTYY","DFD9_JTJJCS"};
         List<String> tempList2 = (List<String>) temp.get("descStr2");
         StringBuffer descxl2 = new StringBuffer();
-        descxl2.append(tempList2.get(0))
-                .append("/r/n")
-                .append(tempList2.get(1));
-        List<Map<String,String>> dataList3 = (List<Map<String, String>>) temp.get("result3");
-        index = this.XlzgzCreateSheet(wb,index,"公变重载明细",titleArray2,fieldArray2,descxl2.toString(),dataList3,new HashMap<String,String>());
+        descxl2
+                .append("  ")
+                .append(tempList2.get(0))
+                .append("\r\n")
+                .append("  ")
+                .append(tempList2.get(1))
+                .append("\r\n")
+                .append("  ")
+                .append("注:配变负载率连续2小时在80%-100%之间为重载,连续2小时在100%以上为过载。");
+        List<Map<String,String>> dataList4 = (List<Map<String, String>>) temp.get("result4");
+        index = ExportUtils.XlzgzCreateSheet(wb,index,"公变重载明细",titleArray2,fieldArray2,descxl2.toString(),dataList4,new HashMap<String,String>());
 
-        //******************************************公变过载明细******************************************//
+        //******************************************公变载明细******************************************//
         titleArray2[3] = "过载时长(h)";
-        List<Map<String,String>> dataList4 = (List<Map<String, String>>) temp.get("result4");
-        index = this.XlzgzCreateSheet(wb,index,"公变过载明细",titleArray2,fieldArray2,"",dataList4,new HashMap<String,String>());
+        fieldArray2[3] = "DFD9_GZSC";
+        List<Map<String,String>> dataList3 = (List<Map<String, String>>) temp.get("result3");
+        index = ExportUtils.XlzgzCreateSheet(wb,index,"公变过载明细",titleArray2,fieldArray2,"",dataList3,new HashMap<String,String>());
 
         //******************************************抢修类工单明细******************************************//
         String[] titleArray3 = new String[]{"客户总量(户)","平均到达现场时间(分)","工单处理平均时长(分)","到达现场超时数",
                 "工单时长超70分钟数","故障类型#客户内部故障","故障类型#低压故障","故障类型#非电力故障","故障类型#电能质量等故障","疑似虚假回单","工单总数","万户报修率"};
         String[] fieldArray3 = new String[]{"1","2","3","4","5","6","7","8","9","10","11","12","13","","","",""};
-        index = this.XlzgzCreateSheet(wb,index,"抢修类工单报表明细",titleArray3,fieldArray3,"",new ArrayList<>(),new HashMap<String,String>());
+        index = ExportUtils.XlzgzCreateSheet(wb,index,"抢修类工单报表明细",titleArray3,fieldArray3,"",new ArrayList<>(),new HashMap<String,String>());
         return wb;
     }
-    private static int XlzgzCreateSheet(XSSFWorkbook wb,int sheetIndex, String sheetName,String[] titleArray,String[] fieldArray,String descStr,List<Map<String,String>> list,Map<String,String> map){
-        XSSFSheet sheet = wb.createSheet(sheetName);
-        int rowIndex = 0;
-        String title = StringUtil.ObjectToString(map.get("title"));
-        if(!"".equals(title)){//标题行
-            XSSFRow row0 = sheet.createRow((int) rowIndex);// 行数从0开始
-            row0.setHeightInPoints(30);//设置行的高度
-            XSSFCell celldesc = row0.createCell(0);
-            sheet.addMergedRegion(new CellRangeAddress(0,0,0,titleArray.length));//合并单元格
-            celldesc.setCellValue(StringUtil.ObjectToString(title));
-            celldesc.setCellStyle(ExportUtils.getDescCellStyle(wb));
-            rowIndex ++;
-        }
-        if(!"".equals(descStr)){//描述行
-            //添加描述行
-            XSSFRow row0 = sheet.createRow((int) rowIndex);// 行数从0开始
-            row0.setHeightInPoints(30);//设置行的高度
-            XSSFCell celldesc = row0.createCell(0);
-            sheet.addMergedRegion(new CellRangeAddress(0,0,0,titleArray.length));//合并单元格
-            celldesc.setCellValue(StringUtil.ObjectToString(descStr));
-            celldesc.setCellStyle(ExportUtils.getDescCellStyle(wb));
-            rowIndex++;
-        }
-        int manyTitle = rowIndex;
-        if(titleArray.length > 0){//标题行
-            if (titleArray != null && titleArray.length > 0){
-                for (int i = 0; i < titleArray.length; i++) {
-                    for (String col : titleArray) {
-                        String[] colTitles = col.split(ExportUtils.COLUMNS_SEPARATOR);
-                        manyTitle = Math.max(manyTitle,colTitles.length);
-                    }
-                }
-            }
-            //重新组装表头
-            titleArray = ExportUtils.autocomplete(titleArray, manyTitle);
-            for (int j = 0; j < manyTitle; j++) {
-                XSSFRow row1 = sheet.createRow((int) rowIndex);
-                //  表头数据填充
-                 for(int i = 0; i < titleArray.length; i++) {
-                    XSSFCell titleCell = row1.createCell(i );// 0号位被序号占用,所以需+1
-                    titleCell.setCellValue(titleArray[i].split("#")[j]);
-                    titleCell.setCellStyle(ExportUtils.getTitleCellStyle(wb));
-                    sheet.setColumnWidth(i, 30 * 256);
-                }
-                rowIndex ++;
-            }
-        }
-        //合并表头
-        ExportUtils.titleMerge(sheet, fieldArray.length, titleArray, manyTitle);
 
-        //数据列
-        for (int i = 0; i < list.size(); i++) {
-            //创建行
-            XSSFRow rowr = sheet.createRow((int) rowIndex + i);
-            for (int j = 0; j < fieldArray.length; j++) {
-                XSSFCell cell = rowr.createCell(j);
-                cell.setCellValue(StringUtil.ObjectToString(list.get(i).get(fieldArray[j])));
-                cell.setCellStyle(ExportUtils.getTextCellStyle(wb));
-            }
-        }
-        return 0;
-    }
+
 }