1. 程式人生 > >Java 實現表格匯出到Excel(.xlsx)

Java 實現表格匯出到Excel(.xlsx)

        最近專案中需要將table 中資料匯出到excel ,當時我想的兩種方案,一種是通過前端外掛TableExport.js。發現簡單使用的話,只是可以匯出table 中原生的資料。一旦table 有jstl 標籤判斷的話,它讀不到。最後採取通過服務端到來實現匯出Excel 格式是.xlsx。這個方案可以匯出大量的資料。分頁顯示。核心程式碼如下;

1、這個公用的方法不帶表頭標題的。

/**
     * 不帶表頭的Excel
     * @param title
     * @param headMap
     * @param jsonArray
     * @param datePattern
     * @param colWidth
     * @param out
     */
    public static void exportToExcel(Map<String, String> headMap,JSONArray jsonArray,String datePattern,int colWidth, OutputStream out) {
        if(datePattern==null) datePattern = DEFAULT_DATE_PATTERN;
        // 宣告一個工作薄
        SXSSFWorkbook workbook = new SXSSFWorkbook(1000);//快取
        workbook.setCompressTempFiles(true);

        // 生成一個表格
        SXSSFSheet sheet = workbook.createSheet();
        //設定列寬
        int minBytes = colWidth<DEFAULT_COLOUMN_WIDTH?DEFAULT_COLOUMN_WIDTH:colWidth;//至少位元組數
        int[] arrColWidth = new int[headMap.size()];
        // 產生表格標題行,以及設定列寬
        String[] properties = new String[headMap.size()];
        String[] headers = new String[headMap.size()];
        int ii = 0;
        for (Iterator<String> iter = headMap.keySet().iterator(); iter
                .hasNext();) {
            String fieldName = iter.next();
            properties[ii] = fieldName;
            headers[ii] = headMap.get(fieldName);
            int bytes = fieldName.getBytes().length;
            arrColWidth[ii] =  bytes < minBytes ? minBytes : bytes;
            sheet.setColumnWidth(ii,arrColWidth[ii]*256);
            ii++;
        }
        // 遍歷集合資料,產生資料行
        int rowIndex = 0;
        for (Object obj : jsonArray) {
            if(rowIndex == 65535 || rowIndex == 0){
                if ( rowIndex != 0 ) sheet = workbook.createSheet();//如果資料超過了,則在第二頁顯示

                SXSSFRow headerRow = sheet.createRow(0); //列頭 rowIndex =1
                for(int i=0;i<headers.length;i++)
                {
                    headerRow.createCell(i).setCellValue(headers[i]);
                }
                rowIndex = 1;//資料內容從 rowIndex=1開始
            }
            JSONObject jo = (JSONObject) JSONObject.toJSON(obj);
            SXSSFRow dataRow = sheet.createRow(rowIndex);
            for (int i = 0; i < properties.length; i++)
            {
                SXSSFCell newCell = dataRow.createCell(i);

                Object o =  jo.get(properties[i]);
                String cellValue = "";
                if(o==null) cellValue = "";
                else if(o instanceof Date) cellValue = new SimpleDateFormat(datePattern).format(o);
                else if(o instanceof Float || o instanceof Double)
                    cellValue= new BigDecimal(o.toString()).setScale(2,BigDecimal.ROUND_HALF_UP).toString();
                else cellValue = o.toString();

                newCell.setCellValue(cellValue);
            }
            rowIndex++;
        }
        // 自動調整寬度
        sheet.trackAllColumnsForAutoSizing();
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }
        try {
            workbook.write(out);
            workbook.close();
            boolean flag =  workbook.dispose();//釋放磁碟空間。處理在磁碟上支援這個工作簿的臨時檔案。呼叫該方法將使工作簿不可用。
            System.out.println(flag);//如果所有臨時檔案都被成功刪除,則為真。
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2、如何呼叫。

 /**
     * 整合資料匯出到Excle
     * 
     * @param response
     * @param userApplyMap
     */
    public void exportExcle(HttpServletResponse response, List<Map<String, Object>> userApplyMap) {
        ServletOutputStream outputStream = null;
        FileInputStream fileInputStream = null;
        String toDir = null;
        try {
            JSONArray userApplyInfos = new JSONArray();
            if (!userApplyMap.isEmpty()) {// 資料集
                for (Map<String, Object> map : userApplyMap) {
                    com.alibaba.fastjson.JSONObject userApply = new com.alibaba.fastjson.JSONObject();
                    userApply.put("userName", map.get("userName"));
                    userApply.put("bankOpeningName", map.get("bankOpeningName"));
                    userApply.put("expenditure", map.get("expenditure"));
                    userApply.put("amount", map.get("amount"));
                    userApply.put("serviceFee", map.get("serviceFee"));
                    userApply.put("bankNo", map.get("bankNo"));
                    userApply.put("withdraw", getWithdrawOrStatus(map, 1));
                    userApply.put("bankOpening", new StringBuilder(
                            map.get("bankOpening").toString() + "\n" + map.get("bankName").toString()));
                    userApply.put("status", getWithdrawOrStatus(map, 2));
                    userApply.put("addTime",
                            DateFormat.getFormatNowTime(Long.parseLong(map.get("addTime").toString()), null));
                    userApplyInfos.add(userApply);
                }
                Map<String, String> headMap = new LinkedHashMap<String, String>();// 存放表頭部資訊
                headMap.put("userName", "賬號");
                headMap.put("bankOpeningName", "收款人");
                headMap.put("expenditure", "金額");
                headMap.put("amount", "金額");
                headMap.put("serviceFee", "手續費");
                headMap.put("bankNo", "賬戶");
                headMap.put("withdraw", "方式");
                headMap.put("bankOpening", "資訊");
                headMap.put("status", "狀態");
                headMap.put("addTime", "申請時間");
                Random random = new Random();
                String title = "提現資訊";
                // 生成檔案臨時存放目錄
                toDir = QuzuUtils.getInstance().getDir(random);
                String path = new StringBuffer().append(toDir).append(title).append(QuzuConst.TYPE_ARRAY[0]).toString();
                OutputStream outXlsx = new FileOutputStream(path);
                ExcelUtil.exportToExcel(headMap, userApplyInfos, null, 0, outXlsx);
                outXlsx.close();
                response.setHeader("Content-Disposition", "attachment;filename="
                        + new String((title + QuzuConst.TYPE_ARRAY[0]).getBytes(), "iso-8859-1"));
                outputStream = response.getOutputStream();
                fileInputStream = new FileInputStream(path);
                byte[] bytes = new byte[1024];
                int size;
                while (-1 != (size = fileInputStream.read(bytes))) {
                    outputStream.write(bytes, 0, size);
                }
                outputStream.flush();
            } else {
                ResponseUtil.write(response, "暫無資料可匯出");
            }
        } catch (Exception e) {
            logger.error("匯出提現資訊異常", e);
        } finally {
            if (fileInputStream != null)
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            if (outputStream != null)
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

        }
        // 刪除臨時檔案
        Utils.getInstance().deleteTempFiles(toDir);
    }

 /**
     * 匯出excle
     * 
     * @param userApplySearchVo
     * @param request
     * @param response
     */
    @RequestMapping("/exportInfo")
    public void exportInfo(UserApplySearchVo userApplySearchVo, HttpServletRequest request,
            HttpServletResponse response) {
        
        try {
            Map<String, Object> params = new HashMap<>();
            creatParams(userApplySearchVo, params);
            List<Map<String, Object>> userAccountApplies = userAccountApplyManageService.selectListWithUserName(params);//查出需要匯出的資料
            exportExcle(response, userAccountApplies);//這裡呼叫
        } catch (Exception e) {
            logger.error("查詢列表異常", e);
        }
    }

3、效果圖,號碼隨便抓的就打碼。