摘要:最近在做使用進行大數(shù)據(jù)量導出,現(xiàn)在把其整理成工具類供大家參考。版本增加了前綴為相關的類,主要用于大數(shù)據(jù)量的寫入與讀取。
最近在做使用POI進行大數(shù)據(jù)量導出,現(xiàn)在把其整理成工具類供大家參考。Apache POI 3.8版本增加了前綴為SXSSF相關的類,主要用于大數(shù)據(jù)量的寫入與讀取。關于ApachePOI導出Excel基本的使用我這里就不詳解了,具體參考:
Apache POI官方網(wǎng)站
Apache POI使用詳解
關于封裝的工具類需要注意:
以下代碼少ReportInternalException大家可以忽略(我們封裝的一個異常類)
導出的Excel同時考慮到數(shù)據(jù)的本身類型,如整數(shù)、小數(shù)、日期等
寫入數(shù)據(jù)方式需依次調用方法[writeExcelTitle、writeExcelData、dispose],先完成寫入Excel標題與列名,再完成數(shù)據(jù)寫入(或者說基于模板方式寫入數(shù)據(jù)),最終關閉流與資源的釋放
我們使用[styleMap]方法避免重復創(chuàng)建Excel單元格樣式(否則受Excel創(chuàng)建樣式數(shù)量限制)
SXSSFWorkbook基于模板寫入數(shù)據(jù)的時候仍需要借助XSSFWorkbook
SXSSFWorkbook寫入數(shù)據(jù)模式大致為:根據(jù)初始化設置的flushRows(內存存儲條數(shù))數(shù)隨著數(shù)據(jù)寫入逐步把數(shù)據(jù)刷新至硬盤,具體參考官方文檔與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 相關操作類(大數(shù)據(jù)量寫入但受Excel數(shù)據(jù)行數(shù)限制) * 先寫入Excel標題(writeExcelTitle),再寫入數(shù)據(jù)(writeExcelData),最后釋放資源(dispose) */ public class ExportExcel2007 { //默認列寬度 private final int DEFAULT_COLUMN_SIZE = 30; //刷新寫入硬盤數(shù)據(jù)閥值 private final int flushRows = 1000; //聲明一個模板工作薄(寫入流式數(shù)據(jù)) private Workbook writeDataWorkBook; //樣式列表 private MapcellStyleMap; //Excel當前數(shù)據(jù)行數(shù)(將要寫入數(shù)據(jù)的索引數(shù)) private int currentRowNum = 0; //數(shù)據(jù)輸出流 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實現(xiàn),先寫入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實現(xiàn),寫入Excel數(shù)據(jù)行列,與writeExcelTitle配合使用 * 先使用writeExcelTitle再使用writeExcelData * * @param directory 目錄 * @param fileName 文件名 * @param sheetName sheetName * @param objects 數(shù)據(jù)信息 */ 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); } } /** * 導出字符串數(shù)據(jù) * * @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)); //寫入成功一行數(shù)據(jù)遞增行數(shù) 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); } //寫入成功一行數(shù)據(jù)遞增行數(shù) 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模板文件不存在"); } } /** * 導出字符串數(shù)據(jù) * * @param objects 目標數(shù)據(jù) */ private void exportExcelData(String sheetName, List > objects) throws ReportInternalException, IOException { // 正文樣式 CellStyle contentStyle = cellStyleMap.get("content"); //正文整數(shù)樣式 CellStyle contentIntegerStyle = cellStyleMap.get("integer"); //正文帶小數(shù)整數(shù)樣式 CellStyle contentDoubleStyle = cellStyleMap.get("double"); // 生成一個表格 Sheet sheet = writeDataWorkBook.getSheet(sheetName); if (sheet == null) { throw new ReportInternalException("讀取Excel模板錯誤"); } // 設置表格默認列寬度 sheet.setDefaultColumnWidth(DEFAULT_COLUMN_SIZE); // 遍歷集合數(shù)據(jù),產生數(shù)據(jù)行,前兩行為標題行與表頭行 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("整數(shù)"); columnNames.add("帶小數(shù)的正數(shù)"); 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
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/65285.html
摘要:并且在對的抽象中,每一行,每一個單元格都是一個對象。對支持使用官方例子需要繼承,覆蓋方法,每讀取到一個單元格的數(shù)據(jù)則會回調次方法。概要Java對Excel的操作一般都是用POI,但是數(shù)據(jù)量大的話可能會導致頻繁的FGC或OOM,這篇文章跟大家說下如果避免踩POI的坑,以及分別對于xls和xlsx文件怎么優(yōu)化大批量數(shù)據(jù)的導入和導出。一次線上問題這是一次線上的問題,因為一個大數(shù)據(jù)量的Excel導出...
摘要:事件將通過添加關注來激活。自動注冊事件監(jiān)聽器通過使用,你可以自動注冊事件監(jiān)聽器,而不需要使用。你可以自由使用這個宏,或者創(chuàng)造你自己的語法以上例子可作對于方法可查看文檔測試測試下載測試存儲導出測試隊列導出 Basics 最簡單的導出方法是創(chuàng)建一個自定義的導出類, 這里我們使用發(fā)票導出作為示例. 在 App/Exports 下創(chuàng)建一個 InvoicesExport 類 namespace...
摘要:實現(xiàn)并發(fā)請求實現(xiàn)并發(fā)請求生成并下載字符串文件首先我們需要了解一個特殊的數(shù)據(jù)格式。如果類型未知,則該值為空字符串。表示狀態(tài)的數(shù)字。一旦完成,屬性中將包含一個字符串以表示所讀取的文件內容。 在web開發(fā)中,如果你想讓用戶下載或者導出一個文件,應該怎么做呢?傳統(tǒng)的做法是在后端存儲或者即時生成一個文件來提供下載功能,這樣的優(yōu)勢是可以做權限控制、數(shù)據(jù)二次處理,但缺點是需要額外發(fā)起請求、增大服務端...
摘要:實現(xiàn)并發(fā)請求實現(xiàn)并發(fā)請求生成并下載字符串文件首先我們需要了解一個特殊的數(shù)據(jù)格式。如果類型未知,則該值為空字符串。表示狀態(tài)的數(shù)字。一旦完成,屬性中將包含一個字符串以表示所讀取的文件內容。 在web開發(fā)中,如果你想讓用戶下載或者導出一個文件,應該怎么做呢?傳統(tǒng)的做法是在后端存儲或者即時生成一個文件來提供下載功能,這樣的優(yōu)勢是可以做權限控制、數(shù)據(jù)二次處理,但缺點是需要額外發(fā)起請求、增大服務端...
閱讀 933·2023-04-26 01:34
閱讀 3367·2023-04-25 20:58
閱讀 3310·2021-11-08 13:22
閱讀 2121·2019-08-30 14:17
閱讀 2533·2019-08-29 15:27
閱讀 2682·2019-08-29 12:45
閱讀 3007·2019-08-29 12:26
閱讀 2821·2019-08-28 17:51