海南版本提交

This commit is contained in:
hzj
2024-03-18 15:21:28 +08:00
parent 5b7763b265
commit 5fff26c276
27 changed files with 1647 additions and 274 deletions

View File

@@ -0,0 +1,88 @@
package com.njcn.advance.utils;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Description:
* Date: 2024/3/15 16:02【需求编号】
*
* @author clam
* @version V1.0.0
*/
@Slf4j
public abstract class EasyExcelDefaultListener<T> extends AnalysisEventListener<T> {
/**
* 批处理阈值
*/
private static final int BATCH_COUNT = 20;
/**
* 用来存放待处理的数据
*/
@Getter
private List<T> list = new ArrayList<>(BATCH_COUNT);
/**
* 读取excel数据前操作 <br>
*
* 只有不读取表头数据时才会触发此方法)
*/
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
log.info("======================================================");
log.info("======================================================");
}
/**
* 读取excel数据操作
* @param obj
* @param context
*/
@Override
public void invoke(T obj, AnalysisContext context) {
list.add(obj);
if (list.size() >= BATCH_COUNT) {
//将数据保存到数据库中
fun(list);
list.clear();
}
}
/**
* 具体业务
*/
protected abstract void fun(List<T> list);
/**
* 读取完excel数据后的操作
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
if (list.size() > 0) {
fun(list);
}
}
/**
* 在读取excel异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。
*/
@Override
public void onException(Exception exception, AnalysisContext context) {
log.error("解析失败,但是继续解析下一行:{}", exception.getMessage());
if (exception instanceof ExcelDataConvertException) {
ExcelDataConvertException ex = (ExcelDataConvertException) exception;
log.error("第{}行,第{}列解析异常,数据为:{}", ex.getRowIndex(), ex.getColumnIndex(), ex.getCellData());
}
}
}

View File

@@ -0,0 +1,379 @@
package com.njcn.advance.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.handler.WriteHandler;
import lombok.SneakyThrows;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Description:
* Date: 2024/3/15 15:58【需求编号】
*
* @author clam
* @version V1.0.0
*/
public class EasyExcelUtil {
//====================================================无JAVA模型读取excel数据===============================================================
/**
* 同步无模型读默认读取sheet0,从第2行开始读
* @param file excel文件的绝对路径
*/
public static List<Map<Integer, String>> syncRead(String file) {
return EasyExcelFactory.read(file).sheet().doReadSync();
}
/**
* 同步无模型读自定义读取sheetX从第2行开始读
* @param file excel文件的绝对路径
* @param sheetNum sheet页号从0开始
*/
public static List<Map<Integer, String>> syncRead(String file, Integer sheetNum) {
return EasyExcelFactory.read(file).sheet(sheetNum).doReadSync();
}
/**
* 同步无模型读指定sheet和表头占的行数
* @param file
* @param sheetNum sheet页号从0开始
* @param headNum 表头占的行数从0开始如果要连表头一起读出来则传0
*/
public static List<Map<Integer, String>> syncRead(String file, Integer sheetNum, Integer headNum) {
return EasyExcelFactory.read(file).sheet(sheetNum).headRowNumber(headNum).doReadSync();
}
/**
* 同步无模型读指定sheet和表头占的行数
* @param inputStream
* @param sheetNum sheet页号从0开始
* @param headNum 表头占的行数从0开始如果要连表头一起读出来则传0
*/
public static List<Map<Integer, String>> syncRead(InputStream inputStream, Integer sheetNum, Integer headNum) {
return EasyExcelFactory.read(inputStream).sheet(sheetNum).headRowNumber(headNum).doReadSync();
}
/**
* 同步无模型读指定sheet和表头占的行数
* @param file
* @param sheetNum sheet页号从0开始
* @param headNum 表头占的行数从0开始如果要连表头一起读出来则传0
*/
public static List<Map<Integer, String>> syncRead(File file, Integer sheetNum, Integer headNum) {
return EasyExcelFactory.read(file).sheet(sheetNum).headRowNumber(headNum).doReadSync();
}
//====================================================无JAVA模型读取excel数据===============================================================
//====================================================将excel数据同步到JAVA模型属性里===============================================================
/**
* 同步按模型读默认读取sheet0,不读取表头从第2行开始读
* @param file
* @param clazz 模型的类类型excel数据会按该类型转换成对象
*/
public static <T> List<T> syncReadModel(String file, Class clazz) {
return EasyExcelFactory.read(file).sheet().head(clazz).doReadSync();
}
/**
* 同步按模型读默认表头占一行不读取表头从第2行开始读
* @param file
* @param clazz 模型的类类型excel数据会按该类型转换成对象
* @param sheetNum sheet页号从0开始
*/
public static <T> List<T> syncReadModel(String file, Class clazz, Integer sheetNum, Integer headNum) {
return EasyExcelFactory.read(file).sheet(sheetNum).headRowNumber(headNum).head(clazz).doReadSync();
}
/**
* 同步按模型读指定sheet,不读取表头)
* @param inputStream
* @param clazz 模型的类类型excel数据会按该类型转换成对象
* @param sheetNum sheet页号从0开始
*/
public static <T> List<T> syncReadModel(InputStream inputStream, Class clazz, Integer sheetNum, Integer headNum) {
return EasyExcelFactory.read(inputStream).sheet(sheetNum).headRowNumber(headNum).head(clazz).doReadSync();
}
/**
* 同步按模型读指定sheet,不读取表头)
* @param file
* @param clazz 模型的类类型excel数据会按该类型转换成对象
* @param sheetNum sheet页号从0开始
*/
public static <T> List<T> syncReadModel(File file, Class clazz, Integer sheetNum, Integer headNum) {
return EasyExcelFactory.read(file).sheet(sheetNum).headRowNumber(headNum).head(clazz).doReadSync();
}
//====================================================将excel数据同步到JAVA模型属性里===============================================================
//====================================================异步读取excel数据===============================================================
/**
* 异步无模型读默认读取sheet0,不读取表头,从第2行开始读
* @param listener 监听器在监听器中可以处理行数据LinkedHashMap表头数据异常处理等
* @param file 表头占的行数从0开始如果要连表头一起读出来则传0
*/
public static <T> void asyncRead(String file, AnalysisEventListener<T> listener) {
EasyExcelFactory.read(file, listener).sheet().doRead();
}
/**
* 异步无模型读(默认表头占一行,不读取表头,从第2行开始读
* @param file 表头占的行数从0开始如果要连表头一起读出来则传0
* @param listener 监听器在监听器中可以处理行数据LinkedHashMap表头数据异常处理等
* @param sheetNum sheet页号从0开始
*/
public static <T> void asyncRead(String file, AnalysisEventListener<T> listener, Integer sheetNum) {
EasyExcelFactory.read(file, listener).sheet(sheetNum).doRead();
}
/**
* 异步无模型读指定sheet和表头占的行数
* @param inputStream
* @param listener 监听器在监听器中可以处理行数据LinkedHashMap表头数据异常处理等
* @param sheetNum sheet页号从0开始
* @param headNum 表头占的行数从0开始如果要连表头一起读出来则传0
*/
public static <T> void asyncRead(InputStream inputStream, AnalysisEventListener<T> listener, Integer sheetNum, Integer headNum) {
EasyExcelFactory.read(inputStream, listener).sheet(sheetNum).headRowNumber(headNum).doRead();
}
/**
* 异步无模型读指定sheet和表头占的行数
* @param file
* @param listener 监听器在监听器中可以处理行数据LinkedHashMap表头数据异常处理等
* @param sheetNum sheet页号从0开始
* @param headNum 表头占的行数从0开始如果要连表头一起读出来则传0
*/
public static <T> void asyncRead(File file, AnalysisEventListener<T> listener, Integer sheetNum, Integer headNum) {
EasyExcelFactory.read(file, listener).sheet(sheetNum).headRowNumber(headNum).doRead();
}
/**
* 异步无模型读指定sheet和表头占的行数
* @param file
* @param listener 监听器在监听器中可以处理行数据LinkedHashMap表头数据异常处理等
* @param sheetNum sheet页号从0开始
* @param headNum 表头占的行数从0开始如果要连表头一起读出来则传0
* @return
*/
public static <T> void asyncRead(String file, AnalysisEventListener<T> listener, Integer sheetNum, Integer headNum) {
EasyExcelFactory.read(file, listener).sheet(sheetNum).headRowNumber(headNum).doRead();
}
//====================================================异步读取excel数据===============================================================
//====================================================将excel数据异步到JAVA模型属性里===============================================================
/**
* 异步按模型读取默认读取sheet0,不读取表头,从第2行开始读
* @param file
* @param listener 监听器在监听器中可以处理行数据LinkedHashMap表头数据异常处理等
* @param clazz 模型的类类型excel数据会按该类型转换成对象
*/
public static <T> void asyncReadModel(String file, AnalysisEventListener<T> listener, Class clazz) {
EasyExcelFactory.read(file, clazz, listener).sheet().doRead();
}
/**
* 异步按模型读取(默认表头占一行,不读取表头,从第2行开始读
* @param file
* @param listener 监听器在监听器中可以处理行数据LinkedHashMap表头数据异常处理等
* @param clazz 模型的类类型excel数据会按该类型转换成对象
* @param sheetNum sheet页号从0开始
*/
public static <T> void asyncReadModel(String file, AnalysisEventListener<T> listener, Class clazz, Integer sheetNum) {
EasyExcelFactory.read(file, clazz, listener).sheet(sheetNum).doRead();
}
/**
* 异步按模型读取
* @param file
* @param listener 监听器在监听器中可以处理行数据LinkedHashMap表头数据异常处理等
* @param clazz 模型的类类型excel数据会按该类型转换成对象
* @param sheetNum sheet页号从0开始
*/
public static <T> void asyncReadModel(File file, AnalysisEventListener<T> listener, Class clazz, Integer sheetNum) {
EasyExcelFactory.read(file, clazz, listener).sheet(sheetNum).doRead();
}
/**
* 异步按模型读取
* @param inputStream
* @param listener 监听器在监听器中可以处理行数据LinkedHashMap表头数据异常处理等
* @param clazz 模型的类类型excel数据会按该类型转换成对象
* @param sheetNum sheet页号从0开始
*/
public static <T> void asyncReadModel(InputStream inputStream, AnalysisEventListener<T> listener, Class clazz, Integer sheetNum) {
EasyExcelFactory.read(inputStream, clazz, listener).sheet(sheetNum).doRead();
}
//====================================================将excel数据异步到JAVA模型属性里===============================================================
//====================================================无JAVA模型写文件===============================================================
/**
* 无模板写文件
* @param file
* @param head 表头数据
* @param data 表内容数据
*/
public static void write(String file, List<List<String>> head, List<List<Object>> data) {
EasyExcel.write(file).head(head).sheet().doWrite(data);
}
/**
* 无模板写文件
* @param file
* @param head 表头数据
* @param data 表内容数据
* @param sheetNum sheet页号从0开始
* @param sheetName sheet名称
*/
public static void write(String file, List<List<String>> head, List<List<Object>> data, Integer sheetNum, String sheetName) {
EasyExcel.write(file).head(head).sheet(sheetNum, sheetName).doWrite(data);
}
//====================================================无JAVA模型写文件===============================================================
//====================================================有Excel模板写文件===============================================================
/**
* 根据excel模板文件写入文件可以实现向已有文件中添加数据的功能
* @param file
* @param template
* @param data
*/
public static <T> void writeTemplate(String file, String template, List<T> data) {
EasyExcel.write(file).withTemplate(template).sheet().doWrite(data);
}
/**
* 根据excel模板文件写入文件
* @param file
* @param template
* @param clazz
* @param data
*/
public static <T> void writeTemplate(String file, String template, Class clazz, List<T> data) {
EasyExcel.write(file, clazz).withTemplate(template).sheet().doWrite(data);
}
//====================================================无模板写文件===============================================================
//====================================================有模板写文件===============================================================
/**
* 按模板写文件
* @param file
* @param clazz 表头模板
* @param data 数据
*/
public static <T> void write(String file, Class clazz, List<T> data) {
EasyExcel.write(file, clazz).sheet().doWrite(data);
}
/**
* 按模板写文件
* @param file
* @param clazz 表头模板
* @param data 数据
* @param sheetNum sheet页号从0开始
* @param sheetName sheet名称
*/
public static <T> void write(String file, Class clazz, List<T> data, Integer sheetNum, String sheetName) {
EasyExcel.write(file, clazz).sheet(sheetNum, sheetName).doWrite(data);
}
/**
* 按模板写文件
* @param file
* @param clazz 表头模板
* @param data 数据
* @param writeHandler 自定义的处理器比如设置table样式设置超链接、单元格下拉框等等功能都可以通过这个实现需要注册多个则自己通过链式去调用
* @param sheetNum sheet页号从0开始
* @param sheetName sheet名称
*/
public static <T> void write(String file, Class clazz, List<T> data, WriteHandler writeHandler, Integer sheetNum, String sheetName) {
EasyExcel.write(file, clazz).registerWriteHandler(writeHandler).sheet(sheetNum, sheetName).doWrite(data);
}
/**
* 按模板写文件(包含某些字段)
* @param file
* @param clazz 表头模板
* @param data 数据
* @param includeCols 包含字段集合,根据字段名称显示
* @param sheetNum sheet页号从0开始
* @param sheetName sheet名称
*/
public static <T> void writeInclude(String file, Class clazz, List<T> data, Set<String> includeCols, Integer sheetNum, String sheetName) {
EasyExcel.write(file, clazz).includeColumnFiledNames(includeCols).sheet(sheetNum, sheetName).doWrite(data);
}
/**
* 按模板写文件(排除某些字段)
* @param file
* @param clazz 表头模板
* @param data 数据
* @param excludeCols 过滤排除的字段,根据字段名称过滤
* @param sheetNum sheet页号从0开始
* @param sheetName sheet名称
*/
public static <T> void writeExclude(String file, Class clazz, List<T> data, Set<String> excludeCols, Integer sheetNum, String sheetName) {
EasyExcel.write(file, clazz).excludeColumnFiledNames(excludeCols).sheet(sheetNum, sheetName).doWrite(data);
}
//------------------------------------------------------------------------------------------------
/**
* 多个sheet页的数据链式写入
*
* @param file
*/
public static EasyExcelWriteTool writeWithSheets(String file) {
return new EasyExcelWriteTool(file);
}
/**
* 多个sheet页的数据链式写入
*
* @param file
*/
public static EasyExcelWriteTool writeWithSheets(File file) {
return new EasyExcelWriteTool(file);
}
/**
* 多个sheet页的数据链式写入
*
* @param outputStream
*/
public static EasyExcelWriteTool writeWithSheets(OutputStream outputStream) {
return new EasyExcelWriteTool(outputStream);
}
/**
* 多个sheet页的数据链式写入失败了会返回一个有部分数据的Excel
*
* @param response
* @param exportFileName 导出的文件名称
*/
@SneakyThrows
public static EasyExcelWriteTool writeWithSheetsWeb(HttpServletResponse response, String exportFileName) throws IOException {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码
String fileName = URLEncoder.encode(exportFileName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
return new EasyExcelWriteTool(response.getOutputStream());
}
}

View File

@@ -0,0 +1,68 @@
package com.njcn.advance.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.apache.poi.ss.formula.functions.T;
import java.io.File;
import java.io.OutputStream;
import java.util.List;
/**
* Description:
* Date: 2024/3/15 16:00【需求编号】
*
* @author clam
* @version V1.0.0
*/
public class EasyExcelWriteTool {
private int sheetNum;
private ExcelWriter excelWriter;
public EasyExcelWriteTool(OutputStream outputStream) {
excelWriter = EasyExcel.write(outputStream).build();
}
public EasyExcelWriteTool(File file) {
excelWriter = EasyExcel.write(file).build();
}
public EasyExcelWriteTool(String filePath) {
excelWriter = EasyExcel.write(filePath).build();
}
/**
* 链式模板表头写入
* @param clazz 表头格式
* @param data 数据 List<ExcelModel> 或者List<List<Object>>
* @return
*/
public <T> EasyExcelWriteTool writeModel(Class clazz, List<T> data, String sheetName) {
final WriteSheet writeSheet = EasyExcel.writerSheet(this.sheetNum++, sheetName).head(clazz).build();
excelWriter.write(data, writeSheet);
return this;
}
/**
* 链式自定义表头写入
* @param head
* @param data 数据 List<ExcelModel> 或者List<List<Object>>
* @param sheetName
* @return
*/
public EasyExcelWriteTool write(List<List<String>> head, List<T> data, String sheetName) {
final WriteSheet writeSheet = EasyExcel.writerSheet(this.sheetNum++, sheetName).head(head).build();
excelWriter.write(data, writeSheet);
return this;
}
/**
* 使用此类结束后,一定要关闭流
*/
public void finish() {
excelWriter.finish();
}
}