Java使用EasyExcel實(shí)現(xiàn)百萬數(shù)據(jù)導(dǎo)出的最佳實(shí)踐指南
報(bào)表下載、數(shù)據(jù)交換、日志歸檔... 導(dǎo)出需求無處不在。但當(dāng)數(shù)據(jù)量膨脹到十萬、百萬級(jí),傳統(tǒng) POI 分分鐘教你做人:內(nèi)存溢出 (OOM)、導(dǎo)出卡成PPT、請求超時(shí) 接踵而至。
別慌!EasyExcel 的「分頁查詢 + 分批寫入」大法,正是為征服海量數(shù)據(jù)而生!本文將帶你:
- 秒懂 EasyExcel 導(dǎo)出優(yōu)化的核心思想
- 手?jǐn)]分頁寫入代碼,輕松hold住百萬行
- 封裝開箱即用的增強(qiáng)工具類,直接CV拿走
- 解鎖動(dòng)態(tài)分頁、異步導(dǎo)出、模板樣式等進(jìn)階技巧
一、痛點(diǎn)直擊:為什么你的導(dǎo)出會(huì)崩?
| 痛點(diǎn) | 癥狀 | 根本原因 |
|---|---|---|
| 內(nèi)存溢出 (OOM) | OutOfMemoryError異常 | 一次性加載全量數(shù)據(jù)進(jìn)內(nèi)存 |
| 導(dǎo)出龜速/卡死 | 頁面轉(zhuǎn)圈圈,接口超時(shí) | 單次處理數(shù)據(jù)量過大,CPU/IO 阻塞 |
| 服務(wù)資源被榨干 | 導(dǎo)出期間,其他接口響應(yīng)變慢 | 導(dǎo)出線程長時(shí)間占用大量資源 |
EasyExcel 的救命稻草:分頁查詢 + 分批寫入
核心思想就八字真言:化整為零,細(xì)嚼慢咽!
- 分頁查詢: 按批次從數(shù)據(jù)庫取數(shù)據(jù) (如每次 2000 條)
- 分批寫入: 取一批,寫一批到 Excel
- 釋放內(nèi)存: 立刻清空當(dāng)前批次數(shù)據(jù),回收內(nèi)存
- 循環(huán)往復(fù): 直到所有數(shù)據(jù)處理完畢
不同規(guī)模數(shù)據(jù)的優(yōu)化策略指南
| 數(shù)據(jù)規(guī)模 | 推薦方案 | 核心機(jī)制 | 內(nèi)存壓力 | 適用場景 |
|---|---|---|---|---|
| < 1萬行 | 普通模式 | 全量加載,一次性寫入 | ?? 中等 | 小報(bào)表、查詢結(jié)果導(dǎo)出 |
| 1萬~50萬行 | 分頁寫入模式 | 分頁查詢 + 分批寫入 | ? 穩(wěn)定 | 業(yè)務(wù)報(bào)表、數(shù)據(jù)備份 |
| > 50萬行 | 分頁+異步 | 異步任務(wù) + 分頁寫入 + 進(jìn)度查詢 | ?? 極低 | 超大數(shù)據(jù)導(dǎo)出、定時(shí)任務(wù) |
重點(diǎn)攻堅(jiān)目標(biāo):1萬~50萬行的分頁寫入模式!
二、基礎(chǔ):小數(shù)據(jù)量的普通導(dǎo)出 (快速回顧)
適用場景: 數(shù)據(jù)量小 (<1萬行),求快求簡單。
@GetMapping("/export/simple")
public void exportSimple(HttpServletResponse response) throws IOException {
// 1??【風(fēng)險(xiǎn)點(diǎn)】全量查詢!數(shù)據(jù)量大必OOM!
List<User> allUsers = userService.findAllUsers();
// 2?? 設(shè)置響應(yīng)頭 (固定套路)
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("用戶列表", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
// 3?? EasyExcel 一鍵寫入
EasyExcel.write(response.getOutputStream(), User.class)
.sheet("用戶信息")
.doWrite(allUsers); // 全量數(shù)據(jù)一次性寫入
}
優(yōu)點(diǎn): 代碼簡單,5分鐘搞定。
致命缺點(diǎn): userService.findAllUsers() 就是顆定時(shí)炸彈,數(shù)據(jù)量稍大直接 OOM!1萬行以上請果斷放棄此方案!
三、核心:分頁寫入模式 (征服10萬+數(shù)據(jù))
這才是處理海量數(shù)據(jù)的正確姿勢!
3.1 分頁寫入核心工具類 (PageWriteExcelHelper)
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import java.io.OutputStream;
import java.util.List;
/**
* 【核心武器】分頁寫入Excel工具 - 專治各種不服(OOM)
*/
public class PageWriteExcelHelper<T> {
// ?? 關(guān)鍵接口:定義如何分頁獲取數(shù)據(jù) (由調(diào)用方實(shí)現(xiàn))
public interface PageQuerySupplier<T> {
List<T> getPage(int pageNum, int pageSize); // 第幾頁? 每頁幾條?
}
/**
* 執(zhí)行分頁寫入
* @param outputStream 輸出流 (響應(yīng)OutputStream)
* @param head 數(shù)據(jù)模型Class (如 User.class)
* @param pageSize 【重要】每批次處理?xiàng)l數(shù) (建議 1000~5000)
* @param totalCount 總數(shù)據(jù)量 (用于計(jì)算總頁數(shù))
* @param supplier 分頁數(shù)據(jù)提供器 (你的業(yè)務(wù)查詢邏輯)
*/
public static <T> void writeByPage(OutputStream outputStream,
Class<T> head,
int pageSize,
int totalCount,
PageQuerySupplier<T> supplier) {
// ?? 1. 初始化 ExcelWriter (EasyExcel 核心寫入器)
ExcelWriter excelWriter = EasyExcel.write(outputStream, head).build();
WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build(); // 默認(rèn)Sheet
try {
// ?? 2. 計(jì)算總頁數(shù) (小心除0)
int totalPage = totalCount > 0 ? (int) Math.ceil((double) totalCount / pageSize) : 1;
// ?? 3. 分頁循環(huán):查詢 -> 寫入 -> 釋放
for (int pageNum = 1; pageNum <= totalPage; pageNum++) {
// ?? 3.1 獲取當(dāng)前頁數(shù)據(jù) (你的分頁查詢)
List<T> pageData = supplier.getPage(pageNum, pageSize);
// ?? 3.2 寫入當(dāng)前頁到 Excel
excelWriter.write(pageData, writeSheet);
// ??? 3.3 【關(guān)鍵】立即清空釋放當(dāng)前頁內(nèi)存!
pageData.clear();
}
} finally {
// ?? 4. 【務(wù)必關(guān)閉】釋放資源 (防止內(nèi)存泄漏)
if (excelWriter != null) {
excelWriter.finish(); // 重要!?。?
}
}
}
}
3.2 如何使用這個(gè)“救命”工具類
@GetMapping("/export/million")
public void exportMassiveData(HttpServletResponse response) throws IOException {
// 1?? 獲取總數(shù)據(jù)量 (用于計(jì)算分頁)
int totalUsers = userService.countTotalUsers();
// 2?? 設(shè)置響應(yīng)頭 (固定套路)
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("百萬用戶數(shù)據(jù)", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
// 3?? 【核心調(diào)用】使用分頁工具類導(dǎo)出
PageWriteExcelHelper.writeByPage(
response.getOutputStream(), // 響應(yīng)輸出流
User.class, // 導(dǎo)出數(shù)據(jù)模型
2000, // 每頁2000條 (根據(jù)業(yè)務(wù)調(diào)整)
totalUsers, // 總數(shù)據(jù)量
// ?? Lambda 實(shí)現(xiàn)分頁查詢邏輯 (優(yōu)雅!)
(pageNum, pageSize) -> userService.findByPage(pageNum, pageSize)
);
}
工具類核心優(yōu)勢:
- 內(nèi)存友好: 每批處理完立刻釋放,內(nèi)存曲線平穩(wěn)
- 通用性強(qiáng): 任何分頁查詢,一個(gè)Lambda搞定
- 資源安全: finally 塊確保
ExcelWriter關(guān)閉 - 簡單易用: 復(fù)雜邏輯封裝,業(yè)務(wù)代碼只需關(guān)注分頁查詢
四、升級(jí):增強(qiáng)版導(dǎo)出工具類 (開箱即用!)
基于核心工具類,我們封裝一個(gè)更強(qiáng)大、更易用的 ExcelExporter,支持文件名設(shè)置、異常處理等。
ExcelExporter.java (終極工具類)
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
/**
* 【開箱即用】EasyExcel 導(dǎo)出增強(qiáng)工具類 (支持普通/分頁模式)
*/
public class ExcelExporter {
// ============== 【1. 分頁寫入 (大數(shù)據(jù)量首選)】 ==============
public static <T> void exportByPage(HttpServletResponse response,
String fileName, // 下載文件名
String sheetName, // Sheet名稱
Class<T> dataModel, // 數(shù)據(jù)類 (User.class)
int pageSize, // 每頁條數(shù)
int totalCount, // 總條數(shù)
PageQuerySupplier<T> pageSupplier) { // 分頁查詢邏輯
setupResponse(response, fileName); // 設(shè)置響應(yīng)頭
try (OutputStream out = response.getOutputStream()) {
// ?? 委托給核心分頁工具執(zhí)行
PageWriteExcelHelper.writeByPage(out, dataModel, pageSize, totalCount, pageSupplier);
} catch (Exception e) {
throw new RuntimeException("導(dǎo)出失敗: " + e.getMessage(), e); // 統(tǒng)一異常處理
}
}
// ============== 【2. 普通導(dǎo)出 (小數(shù)據(jù)量)】 ==============
public static <T> void exportSimple(HttpServletResponse response,
String fileName,
String sheetName,
Class<T> dataModel,
List<T> dataList) { // 全量數(shù)據(jù)List
setupResponse(response, fileName);
try (OutputStream out = response.getOutputStream()) {
EasyExcel.write(out, dataModel)
.sheet(sheetName)
.doWrite(dataList); // 全量寫入
} catch (Exception e) {
throw new RuntimeException("導(dǎo)出失敗: " + e.getMessage(), e);
}
}
// ============== 【私有方法:響應(yīng)頭設(shè)置 (復(fù)用)】 ==============
private static void setupResponse(HttpServletResponse response, String fileName) {
try {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("UTF-8");
String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\+", "%20"); // 處理空格
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
} catch (Exception e) {
throw new RuntimeException("設(shè)置響應(yīng)頭失敗", e);
}
}
// ============== 【內(nèi)部接口:分頁查詢供應(yīng)商】 ==============
@FunctionalInterface
public interface PageQuerySupplier<T> {
List<T> getPage(int pageNum, int pageSize); // 函數(shù)式接口
}
}
使用示例
// 場景1: 導(dǎo)出小數(shù)據(jù)量 (<1萬)
@GetMapping("/export/users/small")
public void exportSmallUserList(HttpServletResponse response) {
List<User> smallList = userService.findRecentUsers(5000); // 查5000條
ExcelExporter.exportSimple(
response,
"最近用戶",
"用戶數(shù)據(jù)",
User.class,
smallList
);
}
// 場景2: 導(dǎo)出大數(shù)據(jù)量 (10萬+)
@GetMapping("/export/users/large")
public void exportLargeUserList(HttpServletResponse response) {
int total = userService.countTotalUsers();
ExcelExporter.exportByPage(
response,
"全量用戶數(shù)據(jù)",
"用戶清單",
User.class,
3000, // 每批3000條
total,
(pageNum, pageSize) -> userService.findByPage(pageNum, pageSize) // 你的分頁查詢
);
}
增強(qiáng)工具類亮點(diǎn):
- 統(tǒng)一入口:
exportSimple和exportByPage清晰區(qū)分場景 - 響應(yīng)頭優(yōu)化: 處理文件名編碼,兼容更多瀏覽器
- 資源安全: 使用
try-with-resources確保流關(guān)閉 - 異常統(tǒng)一: 捕獲異常并轉(zhuǎn)換為
RuntimeException - 開箱即用: 復(fù)制到項(xiàng)目,配置數(shù)據(jù)模型和查詢,立刻起飛!
五、性能優(yōu)化實(shí)戰(zhàn)技巧 (百萬級(jí)也不怕)
技巧 1:動(dòng)態(tài)分頁大小 - 榨干性能!
固定分頁大小不夠智能?試試動(dòng)態(tài)計(jì)算:
public static int calculateOptimalPageSize(Class<?> clazz) {
// 1. 估算單條數(shù)據(jù)大小 (字節(jié)) - 根據(jù)業(yè)務(wù)模型調(diào)整邏輯
long approxBytesPerRow = 500; // 保守估計(jì)500字節(jié)/行
// 2. 獲取當(dāng)前JVM可用內(nèi)存 (轉(zhuǎn)成字節(jié))
long freeMemoryBytes = Runtime.getRuntime().freeMemory();
// 3. 【安全策略】僅使用一部分可用內(nèi)存 (例如 40%)
long safeMemoryToUse = (long) (freeMemoryBytes * 0.4);
// 4. 計(jì)算建議分頁條數(shù)
int suggestedPageSize = (int) (safeMemoryToUse / approxBytesPerRow);
// 5. 設(shè)置合理范圍 (防止太大或太小)
return Math.max(1000, Math.min(suggestedPageSize, 10000)); // 限制在1000~10000條/頁
}
// 使用動(dòng)態(tài)分頁
int dynamicPageSize = calculateOptimalPageSize(User.class);
ExcelExporter.exportByPage(..., dynamicPageSize, ...);
技巧 2:異步導(dǎo)出 + 進(jìn)度查詢 - 用戶體驗(yàn)拉滿!
百萬行導(dǎo)出需要幾十秒?別讓用戶傻等!
// 1. 異步導(dǎo)出接口
@GetMapping("/export/async")
public ResultVo<String> triggerAsyncExport() {
String taskId = "EXPORT_" + System.currentTimeMillis(); // 生成唯一任務(wù)ID
// ?? 提交異步任務(wù) (使用線程池)
asyncTaskExecutor.execute(() -> doExportTask(taskId));
return ResultVo.success("導(dǎo)出任務(wù)已提交,請稍后查詢進(jìn)度", taskId);
}
// 2. 實(shí)際導(dǎo)出任務(wù)
private void doExportTask(String taskId) {
try {
// 2.1 保存任務(wù)狀態(tài) (進(jìn)行中/0%)
exportTaskService.save(new ExportTask(taskId, "PROCESSING", 0));
// 2.2 執(zhí)行分頁導(dǎo)出 (使用我們的ExcelExporter)
int total = userService.countTotalUsers();
AtomicInteger exported = new AtomicInteger(0); // 已導(dǎo)出計(jì)數(shù)器
ExcelExporter.exportByPage(
..., // response 需要特殊處理 (寫文件)
...,
(pageNum, pageSize) -> {
List<User> page = userService.findByPage(pageNum, pageSize);
// ?? 更新進(jìn)度
int currentExported = exported.addAndGet(page.size());
int progress = (int) ((currentExported / (double) total) * 100);
exportTaskService.updateProgress(taskId, progress);
return page;
}
);
// 2.3 任務(wù)完成 (100%)
exportTaskService.updateStatus(taskId, "SUCCESS", 100, filePath); // 存儲(chǔ)文件路徑
} catch (Exception e) {
// 2.4 任務(wù)失敗
exportTaskService.updateStatus(taskId, "FAILED", 0, e.getMessage());
}
}
// 3. 進(jìn)度查詢接口
@GetMapping("/export/progress/{taskId}")
public ResultVo<ExportProgress> getExportProgress(@PathVariable String taskId) {
ExportProgress progress = exportTaskService.getProgress(taskId);
return ResultVo.success(progress);
}
// 4. 文件下載接口 (任務(wù)成功后)
@GetMapping("/export/download/{taskId}")
public void downloadExportFile(@PathVariable String taskId, HttpServletResponse response) {
String filePath = exportTaskService.getFilePath(taskId);
// ... 實(shí)現(xiàn)文件下載邏輯 ...
}
技巧 3:多 Sheet 導(dǎo)出
try (ExcelWriter excelWriter = EasyExcel.write(outputStream).build()) {
List<String> sheetNames = Arrays.asList("用戶信息", "訂單記錄", "操作日志");
for (int i = 0; i < sheetNames.size(); i++) {
WriteSheet sheet = EasyExcel.writerSheet(i, sheetNames.get(i)).head(User.class).build(); // 根據(jù)Sheet設(shè)置不同head
// 對(duì)該Sheet進(jìn)行分頁寫入 (復(fù)用前面的分頁邏輯)...
PageWriteExcelHelper.writeForSheet(excelWriter, sheet, ...);
}
} // try-with-resources自動(dòng)關(guān)閉excelWriter
技巧 4:復(fù)雜樣式?模板導(dǎo)出!
// 1. 提前準(zhǔn)備好帶樣式的 template.xlsx 放在資源目錄
// 2. 模板導(dǎo)出代碼
String templateFile = "/templates/complex-report-template.xlsx";
try (InputStream templateStream = getClass().getResourceAsStream(templateFile);
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
.withTemplate(templateStream)
.build()) {
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// 填充單個(gè)數(shù)據(jù)
excelWriter.fill(new TemplateData(...), writeSheet);
// 填充列表數(shù)據(jù) (支持分頁填充!)
excelWriter.fill(new FillWrapper("dataList", pageData), writeSheet); // 'dataList' 是模板里的變量名
// ... 填充更多數(shù)據(jù) ...
}
六、性能實(shí)測:分頁模式 vs 普通模式
測試環(huán)境: JDK 17 | 4核 CPU | 4GB 內(nèi)存 | MySQL 8.0
| 數(shù)據(jù)量 | 普通模式 | 分頁模式 (2000行/批) | 內(nèi)存峰值對(duì)比 | 結(jié)果 |
|---|---|---|---|---|
| 5千行 | ~350ms | ~400ms | 32MBvs28MB | 差異不大 |
| 5萬行 | ?? ~2.5s (OOM風(fēng)險(xiǎn)) | ~2.3s | 210MBvs48MB | **內(nèi)存降低77%!**? |
| 50萬行 | ? OOM (失敗) | ~10.8s | -vs52MB | 普通模式完全崩掉 |
| 500萬行 | ? 不支持 | ~82s | -vs55MB | 穩(wěn)定輸出,約6.1萬行/秒? |
結(jié)論肉眼可見: 分頁模式在大數(shù)據(jù)量下內(nèi)存占用極其穩(wěn)定,且完全規(guī)避了 OOM 風(fēng)險(xiǎn)!
七、避坑指南 & 最佳實(shí)踐
- 分頁大小不是越大越好: 平衡查詢次數(shù)和內(nèi)存壓力,1000-5000 是經(jīng)驗(yàn)值,或用動(dòng)態(tài)計(jì)算。
- 務(wù)必關(guān)閉 ExcelWriter:
excelWriter.finish()必須放在 finally 塊!否則資源泄漏! - 及時(shí)清除分頁數(shù)據(jù):
pageData.clear()是釋放內(nèi)存的關(guān)鍵一步! - 數(shù)據(jù)庫分頁優(yōu)化: 確保你的分頁查詢 (
getPage) 高效 (使用索引,避免offset過大)。 - 監(jiān)控與日志: 記錄導(dǎo)出任務(wù)耗時(shí)、內(nèi)存變化、行數(shù),方便性能分析和調(diào)優(yōu)。
- 異步+進(jìn)度是大數(shù)據(jù)標(biāo)配: 超過 30 秒的操作,一定要考慮異步和進(jìn)度提示。
- 工具類是你的朋友: 封裝通用邏輯 (
ExcelExporter),減少重復(fù)代碼,降低出錯(cuò)率。
總結(jié)
EasyExcel 的分頁寫入機(jī)制,是征服海量 Excel 導(dǎo)出的利器。通過本文,你掌握了:
- 核心原理: 分頁查詢 + 分批寫入 + 即時(shí)釋放
- 核心武器:
PageWriteExcelHelper分頁寫入工具類 - 終極方案:
ExcelExporter開箱即用增強(qiáng)工具類 - 進(jìn)階技巧: 動(dòng)態(tài)分頁、異步導(dǎo)出、模板樣式
- 避坑經(jīng)驗(yàn): 關(guān)閉Writer、清空數(shù)據(jù)、分頁優(yōu)化
工具類代碼已打包,直接復(fù)制到你的項(xiàng)目就能跑!
以上就是Java使用EasyExcel實(shí)現(xiàn)百萬數(shù)據(jù)導(dǎo)出的最佳實(shí)踐指南的詳細(xì)內(nèi)容,更多關(guān)于Java EasyExcel數(shù)據(jù)導(dǎo)出的資料請關(guān)注腳本之家其它相關(guān)文章!
- java使用EasyExcel導(dǎo)出上萬數(shù)據(jù)如何避免OOM
- Java使用easyExcel導(dǎo)出數(shù)據(jù)及單元格多張圖片
- Java使用easyExcel導(dǎo)出excel數(shù)據(jù)案例
- SpringBoot集成EasyExcel實(shí)現(xiàn)百萬級(jí)別的數(shù)據(jù)導(dǎo)入導(dǎo)出實(shí)踐指南
- Springboot+Easyexcel將數(shù)據(jù)寫入模板文件并導(dǎo)出Excel的操作代碼
- SpringBoot后臺(tái)使用EasyExcel實(shí)現(xiàn)數(shù)據(jù)報(bào)表導(dǎo)出(含模板、樣式、美化)
- SpringBoot種如何使用?EasyExcel?實(shí)現(xiàn)自定義表頭導(dǎo)出并實(shí)現(xiàn)數(shù)據(jù)格式化轉(zhuǎn)換
相關(guān)文章
解決idea中maven項(xiàng)目無端顯示404錯(cuò)誤的方法
這篇文章主要介紹了解決idea中maven項(xiàng)目無端顯示404錯(cuò)誤的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
IDEA中創(chuàng)建maven項(xiàng)目webapp目錄無法識(shí)別即未被標(biāo)識(shí)的解決辦法
在學(xué)習(xí)SpringMVC課程中,基于IDEA新建maven項(xiàng)目模塊后,webapp目錄未被標(biāo)識(shí),即沒有小藍(lán)點(diǎn)的圖標(biāo)顯示,所以本文給大家介紹了IDEA中創(chuàng)建maven項(xiàng)目webapp目錄無法識(shí)別即未被標(biāo)識(shí)的解決辦法,需要的朋友可以參考下2024-03-03
eclipse中自動(dòng)生成javadoc文檔的方法
這篇文章主要介紹了eclipse中自動(dòng)生成javadoc文檔的方法,是實(shí)用eclipse開發(fā)Java程序時(shí)非常實(shí)用的技巧,對(duì)于進(jìn)行Java項(xiàng)目開發(fā)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12
Mybatis步驟分解實(shí)現(xiàn)一個(gè)增刪改查程序
MybatisPlus是國產(chǎn)的第三方插件, 它封裝了許多常用的CURDapi,免去了我們寫mapper.xml的重復(fù)勞動(dòng)。本文將整合MybatisPlus實(shí)現(xiàn)增刪改查功能,感興趣的可以了解一下2022-05-05
Java編程通過匹配合并數(shù)據(jù)實(shí)例解析(數(shù)據(jù)預(yù)處理)
這篇文章主要介紹了Java編程通過匹配合并數(shù)據(jù)實(shí)例解析(數(shù)據(jù)預(yù)處理),分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01

