Forráskód Böngészése

kmall导出excel优化

lhm 3 éve
szülő
commit
dd14bbe2d1

+ 1 - 39
kmall-admin/src/main/java/com/kmall/admin/controller/OrderController.java

@@ -1494,10 +1494,7 @@ public class OrderController {
 
         // =================================================System Format导出结束=====================================
 
-        List<List<Map<String, Object>>> lists = splitList(list, page(list.size()));
-        for (int i = 0; i < lists.size(); i++) {
-            ee.addSheetByMap("Daily sales report " + (i + 1), lists.get(i), header);
-        }
+        ee.addSheetByMap("Daily sales report", list, header);
         ee.export(response);
 
 
@@ -1548,39 +1545,4 @@ public class OrderController {
         return headerMap;
     }
 
-    /**
-     * 根据页数分割集合,分割后的集合一般都会少于3000
-     * 如果大于3000了可能会导出失败
-     * @param list  需要分割的list
-     * @param n     页数
-     * @return      分割后的list集合
-     */
-    public static <T> List<List<T>> splitList(List<T> list, int n){
-        List<List<T>> result = new ArrayList<>();
-        int remainder =list.size() % n;      // 先计算出余数
-        int number = list.size() / n;       // 然后是商
-        int offset = 0;                     // 偏移量
-        for (int i = 0; i < n; i++){
-            List<T> value;
-            if (remainder > 0){
-                value = list.subList(i * number + offset, (i + 1) * number + offset + 1);
-                remainder--;
-                offset++;
-            }else{
-                value = list.subList(i * number + offset, (i + 1) * number + offset);
-            }
-            result.add(value);
-        }
-        return result;
-    }
-
-    /**
-     * 根据集合大小判断有多少页
-     * @param size  集合大小
-     * @return      多少页
-     */
-    private int page(int size) {
-        return size % 3000 == 0 ? size / 3000 : (size / 3000) + 1;
-    }
-
 }

+ 1 - 0
kmall-admin/src/main/webapp/js/shop/offilineOrderList.js

@@ -199,6 +199,7 @@ let vm = new Vue({
             billDate:'',
             storeName:'',
         },
+        flag: true,
         refundMoney: 0,
         shipping: {},
         logisticsInfo: {

+ 35 - 11
kmall-common/src/main/java/com/kmall/common/utils/excel/ExcelExport.java

@@ -22,7 +22,10 @@ import org.apache.poi.hssf.util.HSSFColor;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.RegionUtil;
+import org.apache.poi.xssf.streaming.SXSSFRow;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
 import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFRow;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
@@ -31,6 +34,7 @@ import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
+import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
 import java.sql.Timestamp;
@@ -69,6 +73,12 @@ public class ExcelExport {
     private String exportFileName;
 
     /**
+     * 缓冲大小,SXSSFWorkbook每次的缓冲数量
+     * 达到了就写进磁盘
+     */
+    private int bufferSize = 3000;
+
+    /**
      * 日志
      */
     private Log logger = LogFactory.getLog(ExcelExport.class);
@@ -104,7 +114,7 @@ public class ExcelExport {
         } else if (exportFileName.endsWith(ExcelExport.EXCEL07_EXTENSION)) {
             workBook = new XSSFWorkbook();
         } else {
-            workBook = new SXSSFWorkbook(3000);
+            workBook = new SXSSFWorkbook(bufferSize);
             fileName += ".xlsx";
             // 按正则替换? 处理文件名最后一个字符为“.” 的问题
             // fileName = fileName.replaceAll("..", ".");
@@ -590,17 +600,11 @@ public class ExcelExport {
         int[] cellWidth = new int[cols];
 
         // 取列中最长的行
-        for (int col = 0; col < cols; col++) {
-            for (int row = 0; row < rows; row++) {
-                Cell cell = sheet.getRow(row).getCell(col);
-                String value = getCellValue(cell);
-                int length = value.getBytes().length;
-                if (length > cellWidth[col]) {
-                    cellWidth[col] = length;
-                }
-            }
+        if (sheet instanceof SXSSFSheet) {
+            findColMaxRowLength(cellWidth, rows, ((SXSSFSheet) sheet).getLastFlushedRowNum() + 1, sheet);
+        } else {
+            findColMaxRowLength(cellWidth, rows, 0, sheet);
         }
-
         for (int j = 0; j < cellWidth.length; j++) {
             if (cellWidth[j] > 254) {
                 cellWidth[j] = 254;
@@ -614,6 +618,26 @@ public class ExcelExport {
     }
 
     /**
+     * 取列中最长的行
+     * @param cellWidth     列数组
+     * @param rows          总行数
+     * @param rowValue      开始行数
+     * @param sheet         页
+     */
+    private void findColMaxRowLength(int[] cellWidth, int rows, int rowValue, Sheet sheet){
+        for (int col = 0; col < cellWidth.length; col++) {
+            for (int row = rowValue; row < rows; row++) {
+                Cell cell = sheet.getRow(row).getCell(col);
+                String value = getCellValue(cell);
+                int length = value.getBytes().length;
+                if (length > cellWidth[col]) {
+                    cellWidth[col] = length;
+                }
+            }
+        }
+    }
+
+    /**
      * 主要功能: 取单元格的值
      * 注意事项:按数字和字符两种类型先处理。 BOOLEAN FORMULA 先不处理。 日期格式如何判断?
      *