easyExcel需要的依賴的pom內容;easyExcel需要對應的poi版本,下面這個是一套;否則會報錯;
(異常java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.Font.setBold(Z)V)
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<!--<version>3.8</version>-->
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
<!--<version>3.8</version>-->
</dependency>
<!-- easyExcel處理excel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.2-beta5</version>
</dependency>
--------------
往excel中寫內容:
OutputStream os = new FileOutputStream(new File("C:/Users/zwk/Desktop/測試easyExcel.xlsx"));
ExcelWriter writer = EasyExcelFactory.getWriter(os);
com.alibaba.excel.metadata.Sheet sheet = new com.alibaba.excel.metadata.Sheet(1, 0, ModelBrand.class);
sheet.setSheetName("測試表");
writer.write(modelBrandMapper.getBrandList(), sheet);
writer.finish();
os.close();
注:ModelBrand是插入到excel中的對象模型;這里沒有添加首頁標題,是再ModelBrand類中定義的,且這個類是要繼承BaseRowModel類;modelBrandMapper.getBrandList()是數據集合;
public class ModelBrand extends BaseRowModel {
@ExcelProperty(value="id",index=0)
private Long bId;
@ExcelProperty(value="品牌",index=1)
private String brand;
@ExcelProperty(value="圖片",index=2)
private String img;
@ExcelProperty(value="狀態",index=3)
private Short status;
@ExcelProperty(value="備注",index=4)
private String remark;
@ExcelProperty(value="首字母",index=5)
private String initial;
} value是導出列標題名稱,index是列字段位置;
-------------
//導出excel表格(web項目)
@RequestMapping("/easyExcelTest")
public void easyExcelExport(HttpServletResponse response)throws Exception{
String filename = "easyeexcel列表";
response.setContentType("application/force-download");
response.setHeader("Content-Disposition", "attachment;filename=\"" + java.net.URLEncoder.encode(filename, "UTF-8") + ".xlsx" + "\" ");
//OutputStream os = new FileOutputStream(new File("C:/Users/zwk/Desktop/測試easyExcel.xlsx"));
ExcelWriter writer = EasyExcelFactory.getWriter(response.getOutputStream());
com.alibaba.excel.metadata.Sheet sheet = new com.alibaba.excel.metadata.Sheet(1, 0, ModelBrand.class);
sheet.setSheetName("測試表");
writer.write(modelBrandMapper.getBrandList(), sheet);
writer.finish();
response.getOutputStream().close();
}
----------------
讀取excel文件數據:這里ModelInfoCopyMapper需要注入進來;這里使用構造方法將該參數傳遞進來
/**
* 異步讀取excel文件中的數據;
* 讀取excel文件中的指定數量,分批處理excel文件,解決占用內存的問題。
* 利用poi當遇到表格數據是數值時,實際類中定義的是字符串,讀取的時候就需要
* 指定讀取單元格的類型;而利用easyExcel模型無需這樣,可以為空,null,數值類型,無需特別處理。
* @Author:
* @Date: 2019/10/16 11:58
* @Version 1.0.0
* @Description
*/
public class ExcelModelListener extends AnalysisEventListener<ModelInfoCopy> {
private ModelInfoCopyMapper modelInfoCopyMapper;
public ExcelModelListener(ModelInfoCopyMapper modelInfoCopyMapper){
this.modelInfoCopyMapper = modelInfoCopyMapper;
}
public ExcelModelListener(){
}
//public static ModelInfoCopyMapper modelInfoCopyMapper = SpringBeanUtil.getBean(ModelInfoCopyMapper.class);
//一次讀取50條數據,處理50條可以根據具體情況讀取(若數據大,可以調整一次讀取2000條數據);
private static final int BATCH_COUNT = 2000;
List<ModelInfoCopy> list = new ArrayList<>();
private static int count = 0;
@Override
public void invoke(ModelInfoCopy modelInfoCopy, AnalysisContext analysisContext) {
//System.out.println("解析到一條數據:"+modelBrand.toString());
list.add(modelInfoCopy);
count++;
if(list.size() >= BATCH_COUNT){
saveData(count);
//清理list占用內存空間
list.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//這個方法調用若注釋了,那么最后一批的數據就不會處理
saveData(count);
System.out.println("所有數據解析完成!"+"共處理"+count+"條數據");
}
//處理數據的方法
private void saveData(int count){
System.out.println(count+"條數據,開始存儲數據庫");
for(ModelInfoCopy modelInfoCopy : list){
modelInfoCopyMapper.insert(modelInfoCopy);
//System.out.println(modelBrand.getbId()+","+modelBrand.getBrand()+","+modelBrand.getRemark());
}
System.out.println("存儲數據庫成功");
}
}
//調用方法:這里處理十萬數據,添加到數據庫中需要206946毫秒,40個字段;30萬條數據需要10分鍾。
//使用poi處理的話,4萬數據就會出現內存溢出異常。
@Test
public void test16(){
String filePath = "C:/Users/zwk/Desktop/車型數據(含編碼)20191014.xlsx";
try{
long beforTime = System.currentTimeMillis();
com.alibaba.excel.metadata.Sheet sheet = new com.alibaba.excel.metadata.Sheet(1,1,ModelInfoCopy.class);
EasyExcelFactory.readBySax(new FileInputStream(new File(filePath)),sheet ,new ExcelModelListener(modelInfoCopyMapper) );
System.out.println("讀取數據所花的時間:"+(System.currentTimeMillis()-beforTime)+"毫秒");
}catch (Exception e){
e.printStackTrace();
}
}
注:com.alibaba.excel.metadata.Sheet(1,1,ModelInfoCopy.class);是從第二行讀取的,過濾調了標題行;第一個”1“代表的是excel文件中的第一個表格;第二個”1“代表表格的第幾行開始讀取。
/**
* @Author: 普通類獲取spring容器中的bean
* @Date: 2019/10/16 14:42
* @Version 1.0.0
* @Description
*/
public class SpringBeanUtil {
//將管理上下文的applicationContext設置成靜態變量,供全局調用
public static ConfigurableApplicationContext applicationContext;
//定義一個獲取已經實例化bean的方法
public static <T> T getBean(Class<T> c){
return applicationContext.getBean(c);
}
}