摘要:最近在做使用進行大數據量導出,現在把其整理成工具類供大家參考。版本增加了前綴為相關的類,主要用于大數據量的寫入與讀取。
最近在做使用POI進行大數據量導出,現在把其整理成工具類供大家參考。Apache POI 3.8版本增加了前綴為SXSSF相關的類,主要用于大數據量的寫入與讀取。關于ApachePOI導出Excel基本的使用我這里就不詳解了,具體參考:
Apache POI官方網站
Apache POI使用詳解
關于封裝的工具類需要注意:
以下代碼少ReportInternalException大家可以忽略(我們封裝的一個異常類)
導出的Excel同時考慮到數據的本身類型,如整數、小數、日期等
寫入數據方式需依次調用方法[writeExcelTitle、writeExcelData、dispose],先完成寫入Excel標題與列名,再完成數據寫入(或者說基于模板方式寫入數據),最終關閉流與資源的釋放
我們使用[styleMap]方法避免重復創建Excel單元格樣式(否則受Excel創建樣式數量限制)
SXSSFWorkbook基于模板寫入數據的時候仍需要借助XSSFWorkbook
SXSSFWorkbook寫入數據模式大致為:根據初始化設置的flushRows(內存存儲條數)數隨著數據寫入逐步把數據刷新至硬盤,具體參考官方文檔與API介紹
XSSFWorkbook tplWorkBook = new XSSFWorkbook(new FileInputStream(file)); Workbook writeDataWorkBook = new SXSSFWorkbook(tplWorkBook, flushRows);
Maven依賴配置
使用的Apache POI版本
3.9
org.apache.poi poi ${poi.version} org.apache.poi poi-ooxml ${poi.version} org.apache.poi poi-ooxml-schemas ${poi.version}
import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFFont; import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.*; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * Excel 相關操作類(大數據量寫入但受Excel數據行數限制) * 先寫入Excel標題(writeExcelTitle),再寫入數據(writeExcelData),最后釋放資源(dispose) */ public class ExportExcel2007 { //默認列寬度 private final int DEFAULT_COLUMN_SIZE = 30; //刷新寫入硬盤數據閥值 private final int flushRows = 1000; //聲明一個模板工作薄(寫入流式數據) private Workbook writeDataWorkBook; //樣式列表 private MapcellStyleMap; //Excel當前數據行數(將要寫入數據的索引數) private int currentRowNum = 0; //數據輸出流 private OutputStream outputStream; /** * 斷言Excel文件寫入之前的條件 * * @param directory 目錄 * @param fileName 文件名 * @return file * @throws IOException */ private File assertFile(String directory, String fileName) throws IOException { File tmpFile = new File(directory + File.separator + fileName + ".xlsx"); if (tmpFile.exists()) { if (tmpFile.isDirectory()) { throw new IOException("File "" + tmpFile + "" exists but is a directory"); } if (!tmpFile.canWrite()) { throw new IOException("File "" + tmpFile + "" cannot be written to"); } } else { File parent = tmpFile.getParentFile(); if (parent != null) { if (!parent.mkdirs() && !parent.isDirectory()) { throw new IOException("Directory "" + parent + "" could not be created"); } } } return tmpFile; } /** * 日期轉化為字符串,格式為yyyy-MM-dd HH:mm:ss */ private String getCnDate(Date date) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(date); } /** * Excel 導出,POI實現,先寫入Excel標題,與writeExcelData配合使用 * 先使用writeExcelTitle再使用writeExcelData * * @param directory 目錄 * @param fileName 文件名 * @param sheetName sheetName * @param columnNames 列名集合 * @param sheetTitle 表格標題 */ public void writeExcelTitle(String directory, String fileName, String sheetName, List columnNames, String sheetTitle) throws ReportInternalException, IOException { File tmpFile = assertFile(directory, fileName); exportExcelTitle(tmpFile, sheetName, columnNames, sheetTitle); loadTplWorkbook(tmpFile); } /** * Excel 導出,POI實現,寫入Excel數據行列,與writeExcelTitle配合使用 * 先使用writeExcelTitle再使用writeExcelData * * @param directory 目錄 * @param fileName 文件名 * @param sheetName sheetName * @param objects 數據信息 */ public void writeExcelData(String directory, String fileName, String sheetName, List > objects) throws ReportInternalException, IOException { File tmpFile = assertFile(directory, fileName); outputStream = new FileOutputStream(tmpFile); exportExcelData(sheetName, objects); } /** * 釋放資源 */ public void dispose() throws ReportInternalException { try { if (writeDataWorkBook != null) { writeDataWorkBook.write(outputStream); } if (outputStream != null) { outputStream.flush(); outputStream.close(); } if (cellStyleMap != null) { cellStyleMap.clear(); } cellStyleMap = null; outputStream = null; writeDataWorkBook = null; } catch (IOException e) { throw new ReportInternalException(e); } } /** * 導出字符串數據 * * @param file 文件名 * @param columnNames 表頭 * @param sheetTitle sheet頁Title */ private void exportExcelTitle(File file, String sheetName, List
columnNames, String sheetTitle) throws ReportInternalException { Workbook tplWorkBook = new XSSFWorkbook(); Map cellStyleMap = styleMap(tplWorkBook); // 表頭樣式 CellStyle headStyle = cellStyleMap.get("head"); // 生成一個表格 Sheet sheet = tplWorkBook.getSheet(sheetName); if (sheet == null) { sheet = tplWorkBook.createSheet(sheetName); } //最新Excel列索引,從0開始 //int lastRowIndex = sheet.getLastRowNum(); // 設置表格默認列寬度 sheet.setDefaultColumnWidth(DEFAULT_COLUMN_SIZE); // 合并單元格 sheet.addMergedRegion(new CellRangeAddress(currentRowNum, currentRowNum, 0, columnNames.size() - 1)); // 產生表格標題行 Row rowMerged = sheet.createRow(currentRowNum); Cell mergedCell = rowMerged.createCell(0); mergedCell.setCellStyle(headStyle); mergedCell.setCellValue(new XSSFRichTextString(sheetTitle)); //寫入成功一行數據遞增行數 currentRowNum = currentRowNum + 1; // 產生表格表頭列標題行 Row row = sheet.createRow(currentRowNum); for (int i = 0; i < columnNames.size(); i++) { Cell cell = row.createCell(i); cell.setCellStyle(headStyle); RichTextString text = new XSSFRichTextString(columnNames.get(i)); cell.setCellValue(text); } //寫入成功一行數據遞增行數 currentRowNum = currentRowNum + 1; try { OutputStream ops = new FileOutputStream(file); tplWorkBook.write(ops); ops.flush(); ops.close(); } catch (IOException e) { throw new ReportInternalException(e); } } /** * 加載模板文件 */ private void loadTplWorkbook(File file) throws ReportInternalException { try { XSSFWorkbook tplWorkBook = new XSSFWorkbook(new FileInputStream(file)); writeDataWorkBook = new SXSSFWorkbook(tplWorkBook, flushRows); cellStyleMap = styleMap(writeDataWorkBook); } catch (IOException e) { throw new ReportInternalException("Excel模板文件不存在"); } } /** * 導出字符串數據 * * @param objects 目標數據 */ private void exportExcelData(String sheetName, List > objects) throws ReportInternalException, IOException { // 正文樣式 CellStyle contentStyle = cellStyleMap.get("content"); //正文整數樣式 CellStyle contentIntegerStyle = cellStyleMap.get("integer"); //正文帶小數整數樣式 CellStyle contentDoubleStyle = cellStyleMap.get("double"); // 生成一個表格 Sheet sheet = writeDataWorkBook.getSheet(sheetName); if (sheet == null) { throw new ReportInternalException("讀取Excel模板錯誤"); } // 設置表格默認列寬度 sheet.setDefaultColumnWidth(DEFAULT_COLUMN_SIZE); // 遍歷集合數據,產生數據行,前兩行為標題行與表頭行 for (List
import java.io.IOException; import java.sql.Date; import java.util.LinkedList; import java.util.List; public class ExcelExport { public static void main(String[] args) throws IOException { String sheetName = "測試Excel格式"; String sheetTitle = "測試Excel格式"; ListcolumnNames = new LinkedList<>(); columnNames.add("日期-String"); columnNames.add("日期-Date"); columnNames.add("時間戳-Long"); columnNames.add("客戶編碼"); columnNames.add("整數"); columnNames.add("帶小數的正數"); ExportExcel2007 exportExcel2007 = new ExportExcel2007(); exportExcel2007.writeExcelTitle("E: emp", "a", sheetName, columnNames, sheetTitle); for (int j = 0; j < 2; j++) { List > objects = new LinkedList<>(); for (int i = 0; i < 1000; i++) { List
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/65285.html
摘要:并且在對的抽象中,每一行,每一個單元格都是一個對象。對支持使用官方例子需要繼承,覆蓋方法,每讀取到一個單元格的數據則會回調次方法。概要Java對Excel的操作一般都是用POI,但是數據量大的話可能會導致頻繁的FGC或OOM,這篇文章跟大家說下如果避免踩POI的坑,以及分別對于xls和xlsx文件怎么優化大批量數據的導入和導出。一次線上問題這是一次線上的問題,因為一個大數據量的Excel導出...
摘要:事件將通過添加關注來激活。自動注冊事件監聽器通過使用,你可以自動注冊事件監聽器,而不需要使用。你可以自由使用這個宏,或者創造你自己的語法以上例子可作對于方法可查看文檔測試測試下載測試存儲導出測試隊列導出 Basics 最簡單的導出方法是創建一個自定義的導出類, 這里我們使用發票導出作為示例. 在 App/Exports 下創建一個 InvoicesExport 類 namespace...
摘要:實現并發請求實現并發請求生成并下載字符串文件首先我們需要了解一個特殊的數據格式。如果類型未知,則該值為空字符串。表示狀態的數字。一旦完成,屬性中將包含一個字符串以表示所讀取的文件內容。 在web開發中,如果你想讓用戶下載或者導出一個文件,應該怎么做呢?傳統的做法是在后端存儲或者即時生成一個文件來提供下載功能,這樣的優勢是可以做權限控制、數據二次處理,但缺點是需要額外發起請求、增大服務端...
摘要:實現并發請求實現并發請求生成并下載字符串文件首先我們需要了解一個特殊的數據格式。如果類型未知,則該值為空字符串。表示狀態的數字。一旦完成,屬性中將包含一個字符串以表示所讀取的文件內容。 在web開發中,如果你想讓用戶下載或者導出一個文件,應該怎么做呢?傳統的做法是在后端存儲或者即時生成一個文件來提供下載功能,這樣的優勢是可以做權限控制、數據二次處理,但缺點是需要額外發起請求、增大服務端...
閱讀 931·2023-04-26 01:34
閱讀 3365·2023-04-25 20:58
閱讀 3296·2021-11-08 13:22
閱讀 2119·2019-08-30 14:17
閱讀 2527·2019-08-29 15:27
閱讀 2680·2019-08-29 12:45
閱讀 3006·2019-08-29 12:26
閱讀 2818·2019-08-28 17:51