当前位置:网站首页>Easyexcel read write simple to use
Easyexcel read write simple to use
2022-07-07 10:18:00 【wnfee】
List of articles
Official documents https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read
One . Read
1.1 Defining entity classes
@Data
public class EmailImportParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = " Data adding method 1 The system automatically finds the registered company name through the email domain name 2 Manual input ")
@NotNull
@ExcelProperty(index = 0)
private Integer dataType;
@ApiModelProperty(value = " Alternate company name ")
@ExcelProperty(index = 1)
private String inputCompanyName;
@ApiModelProperty(value = " Email address ")
@NotBlank
@ExcelProperty(index = 2)
private String email;
}
- If you don't use headings
@ExcelProperty(index = 0), Title From0Turn on- If you use the title
@ExcelProperty(" Data adding method ")
1.2 Do not check data batch import
Interface implementation
@Override
@SneakyThrows
public Boolean importExcel(MultipartFile file) {
EasyExcel.read(file.getInputStream(), EmailImportParam.class, new EmailDataListener(this)).sheet().doRead();
return true;
}
add to EmailDataListener
package com.tophant.pentestinfoinv.listener;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.tophant.pentestinfoinv.common.domain.query.EmailAddParam;
import com.tophant.pentestinfoinv.common.domain.query.EmailImportParam;
import com.tophant.pentestinfoinv.service.IEmailService;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @Description email excel Import listening class
* @Author WanFei
* @Date 2022/7/4 16:43
**/
@Slf4j
public class EmailDataListener implements ReadListener<EmailImportParam> {
/**
* every other 5 Storage database , It can be used in practice 100 strip , Then clean up list , Convenient for memory recycling
*/
private static final int BATCH_COUNT = 100;
private List<EmailImportParam> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
/**
* Suppose this is a DAO, Of course, there is business logic, which can also be a service. Of course, it's useless if you don't have to store this object .
*/
private IEmailService emailService;
/**
* If used spring, Please use this construction method . Each creation Listener You need to put spring The management class came in
*
* @param emailService
*/
public EmailDataListener(IEmailService emailService) {
this.emailService = emailService;
}
/**
* Every data parsing will call
*
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(EmailImportParam data, AnalysisContext context) {
log.info(" Parse to a piece of data :{}", JSONUtil.toJsonStr(data));
cachedDataList.add(data);
// achieve BATCH_COUNT 了 , Need to store the database once , Prevent tens of thousands of data in memory , Easy to OOM
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
// Storage complete cleaning list
cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
}
}
/**
* All data analysis is done Will call
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// We also need to save data here , Make sure that the last legacy data is also stored in the database
saveData();
log.info(" All data analysis completed !");
}
/**
* Plus the storage database
*/
private void saveData() {
log.info("{} Data , Start storing the database !", cachedDataList.size());
List<EmailAddParam> emailAddParams = cachedDataList.stream().map(emailImportParam -> new EmailAddParam()
.setEmails(Set.of(emailImportParam.getEmail()))
.setDataType(emailImportParam.getDataType())
.setInputCompanyName(emailImportParam.getInputCompanyName()))
.collect(Collectors.toList());
emailAddParams.forEach(emailService::create);
log.info(" Storage database success !");
}
}
1.3 Check the one-time import of data
@Override
@SneakyThrows
public Boolean importExcel(MultipartFile file) {
File newFile = MultipartFileUtil.multipartFileToFile(file);
Assert.isFalse(ObjectUtil.isNull(file) || ObjectUtil.isNull(newFile), " The file cannot be empty !");
// Get file type
String fileType = FileUtil.getType(newFile);
log.info(" Upload file extension : {}", fileType);
Assert.notNull(fileType, " The extension name of the uploaded file is empty !");
Assert.isTrue(StrUtil.containsAnyIgnoreCase(fileType, "xls", "xlsx"), StrUtil.format(" Upload of file type is not allowed : {}", fileType));
List<EmailImportParam> emailList = new ArrayList<>();
EasyExcel.read(file.getInputStream()).head(EmailImportParam.class)
.sheet()
.registerReadListener(new AnalysisEventListener<EmailImportParam>() {
@Override
public void invoke(EmailImportParam data, AnalysisContext context) {
emailList.add(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info(" Data read complete ");
}
}).doRead();
Set<String> emails = emailList.stream().map(EmailImportParam::getEmail).collect(Collectors.toSet());
InfoInvUtil.checkDomain(emails);
// Query the existing mailbox
Set<String> repeatEmails = this.lambdaQuery()
.eq(Email::getDelFlag, false)
.in(Email::getEmail, emails)
.select(Email::getEmail)
.list()
.stream()
.map(Email::getEmail)
.collect(Collectors.toSet());
Assert.isFalse(CollUtil.isNotEmpty(repeatEmails), StrUtil.format(" mailbox : {} Already exists , Please check excel file ", CollUtil.join(repeatEmails, ", ")));
// Add to database
List<EmailAddParam> emailAddParams = emailList.stream().map(emailImportParam -> new EmailAddParam()
.setEmails(Set.of(emailImportParam.getEmail()))
.setDataType(emailImportParam.getDataType())
.setInputCompanyName(emailImportParam.getInputCompanyName()))
.collect(Collectors.toList());
emailAddParams.forEach(this::create);
return true;
}
MultipartFileUtil Tool class
package com.tophant.pentestinfoinv.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Objects;
/**
* File Transformation tool
*
* @author [email protected]
* @date 06-21-0021-2021
*/
@Slf4j
public class MultipartFileUtil {
/**
* MultipartFile Convert to File
*
* @param file multipartFile
* @return File
* @throws Exception
*/
public static File multipartFileToFile(MultipartFile file) {
try {
File toFile = null;
if (file.equals("") || file.getSize() <= 0) {
file = null;
} else {
InputStream ins = null;
ins = file.getInputStream();
toFile = new File(Objects.requireNonNull(file.getOriginalFilename()));
inputStreamToFile(ins, toFile);
ins.close();
}
return toFile;
} catch (Exception e) {
log.warn("MultipartFile Turn into File Failure !");
return null;
}
}
/**
* Get stream file
* @param ins
* @param file
*/
private static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Two . write in
2.1 write in
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
EasyExcel.write(byteArrayOutputStream, EmailExcelVO.class)
// Register a custom interceptor
.registerWriteHandler(new CustomCellWriteConfig())
.registerWriteHandler(new CustomColumnWidthConfig())
.registerWriteHandler(new CustomRowHeightConfig())
.sheet(" mailbox ")
.doWrite(excelVOList);
2.2 Custom interceptors
2.2.1 Set the style
package com.tophant.component.starter.excel.common.config;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.*;
import java.util.List;
/**
* @Description Set the style
* @Author WanFei
* @Date 2022/5/13 12:13
*/
public class CustomCellWriteConfig implements CellWriteHandler {
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
CellStyle cellStyle = workbook.createCellStyle();
// In the middle
cellStyle.setAlignment(HorizontalAlignment.LEFT);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
// Set borders
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
// Word wrap
cellStyle.setWrapText(true);
// Configuration takes effect
cell.setCellStyle(cellStyle);
}
}
2.2.2 Adaptive width
package com.tophant.component.starter.excel.common.config;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.util.CollectionUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description Adaptive width
* @Author WanFei
* @Date 2022/5/13 13:59
*/
public class CustomColumnWidthConfig extends AbstractColumnWidthStyleStrategy {
private Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>();
@Override
protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) {
boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
if (needSetWidth) {
Map<Integer, Integer> maxColumnWidthMap = CACHE.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>());
Integer columnWidth = this.dataLength(cellDataList, cell, isHead);
if (columnWidth >= 0) {
if (columnWidth > 254) {
columnWidth = 254;
}
Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());
if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);
Sheet sheet = writeSheetHolder.getSheet();
sheet.setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
}
}
}
}
/**
* Calculate the length
* @param cellDataList
* @param cell
* @param isHead
* @return
*/
private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
if (isHead) {
return cell.getStringCellValue().getBytes().length;
} else {
CellData<?> cellData = cellDataList.get(0);
CellDataTypeEnum type = cellData.getType();
if (type == null) {
return -1;
} else {
switch (type) {
case STRING:
// A newline ( The data needs to be parsed in advance )
int index = cellData.getStringValue().indexOf("\n");
return index != -1 ?
cellData.getStringValue().substring(0, index).getBytes().length + 1 : cellData.getStringValue().getBytes().length + 1;
case BOOLEAN:
return cellData.getBooleanValue().toString().getBytes().length;
case NUMBER:
return cellData.getNumberValue().toString().getBytes().length;
default:
return -1;
}
}
}
}
}
2.2.3 Adaptive line height
package com.tophant.component.starter.excel.common.config;
import com.alibaba.excel.write.style.row.AbstractRowHeightStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import java.util.Iterator;
/**
* @Description Adaptive line height
* @Author WanFei
* @Date 2022/5/13 14:03
*/
public class CustomRowHeightConfig extends AbstractRowHeightStyleStrategy {
/**
* Default height
*/
private static final Integer DEFAULT_HEIGHT = 300;
@Override
protected void setHeadColumnHeight(Row row, int relativeRowIndex) {
}
@Override
protected void setContentColumnHeight(Row row, int relativeRowIndex) {
Iterator<Cell> cellIterator = row.cellIterator();
if (!cellIterator.hasNext()) {
return;
}
// The default is 1 Line height
Integer maxHeight = 1;
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case STRING:
if (cell.getStringCellValue().contains("\n")) {
int length = cell.getStringCellValue().split("\n").length;
maxHeight = Math.max(maxHeight, length);
}
break;
default:
break;
}
}
row.setHeight((short) (maxHeight * DEFAULT_HEIGHT));
}
}
边栏推荐
猜你喜欢
随机推荐
每周推荐短视频:L2级有哪些我们日常中经常会用到的功能?
【剑指Offer】42. 栈的压入、弹出序列
Appx code signing Guide
Bean operation domain and life cycle
A wave of open source notebooks is coming
Smart city construction based on GIS 3D visualization technology
LeetCode 练习——113. 路径总和 II
ArcGIS operation: converting DWG data to SHP data
Bit operation ==c language 2
Chris Lattner, père de llvm: Pourquoi reconstruire le logiciel d'infrastructure ai
Or in SQL, what scenarios will lead to full table scanning
The method of word automatically generating directory
ES类和对象、原型
喜马拉雅网页版每次暂停后弹窗推荐下载客户端解决办法
Why does the starting service report an error when installing MySQL? (operating system Windows)
Postman interface test I
Official media attention! The list of top 100 domestic digital collection platforms was released, and the industry accelerated the healthy development of compliance
LLVM之父Chris Lattner:為什麼我們要重建AI基礎設施軟件
STM32产品介绍
搭建物联网硬件通信技术几种方案









