Commit 84248c81 authored by wangqiang's avatar wangqiang

添加:使用EasyExcel插件实现采购计划导入数据功能

parent b4158d7d
...@@ -86,6 +86,11 @@ ...@@ -86,6 +86,11 @@
<version>2.17.1</version> <version>2.17.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.4</version>
</dependency>
</dependencies> </dependencies>
......
package com.yonde.dcs.plan.common.listener;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import com.yonde.dcs.plan.common.vo.ExtPuchasePlanExcelVO;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
public class PurchasePlanExcelListenner extends AnalysisEventListener<ExtPuchasePlanExcelVO> {
/**
* 每隔100条处理下,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 100;
/**
* 缓存的数据
*/
private List<ExtPuchasePlanExcelVO> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
@Override
public void invoke(ExtPuchasePlanExcelVO extPuchasePlanExcelVO, AnalysisContext analysisContext) {
log.info("解析到一条数据:{}", extPuchasePlanExcelVO);
cachedDataList.add(extPuchasePlanExcelVO);
if (cachedDataList.size() >= BATCH_COUNT) {
// 处理缓存的数据,比如说入库。。。
// 然后清空
//todo 需要处理采购计划数据到数据库
cachedDataList.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 收尾工作,处理剩下的缓存数据。。。
log.info("sheet={} 所有数据解析完成!", analysisContext.readSheetHolder().getSheetName());
}
/**
*
* @param exception
* @param context
* @throws Exception
*/
@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {
log.error("======>>>解析异常:", exception);
throw exception;
}
//todo wq测试代码
// public static void main(String[] args) {
// String fileName = "F:\\yangyi\\项目\\清华核研院\\核研院设计文档及原型\\采购计划导入模板.xlsx";
// EasyExcel.read(fileName, ExtPuchasePlanExcelVO.class, new PurchasePlanExcelListenner()).sheet().doRead();
// }
}
package com.yonde.dcs.plan.common.utils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EasyExcelUtils {
private static final Logger log = LoggerFactory.getLogger(EasyExcelUtils.class);
/**
* 导出Excel返回文件的File
*
* @param data
* @param clazz
* @param fileName
*/
public static <T> File exportReturnToFile(List<T> data, Class<T> clazz, String fileName) {
File file = null;
//名称拆分前后缀
//1.判断文件名是否有扩展
try {
if (StringUtils.isBlank(fileName)) {
file = File.createTempFile(fileName, "");
} else {
String[] parts = fileName.split("\\.");
String extension = "." + parts[parts.length - 1];
String name = fileName.substring(0, fileName.length() - extension.length() - 1);
file = File.createTempFile(name, extension);
}
} catch (IOException e) {
log.error("文件生成失败,文件名异常.异常信息:{}", e.getMessage());
throw new RuntimeException("文件生成失败,文件名异常");
}
//导出
EasyExcel.write(file, clazz)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(defaultStylePolicyPolicy())
.sheet()
.doWrite(data);
return file;
}
/**
* EasyExce导出到浏览器(类模板方式)
*
* @param fileName 文件名
* @param response 响应对象
* @param data 数据集
* @param clazz 实体类模板
* @param <T> 泛型
*/
public static <T> void export(String fileName, HttpServletResponse response, List<T> data, Class<T> clazz) throws IOException {
exportPublic(fileName, response, data, clazz, null);
}
/**
* EasyExce导出到浏览器(类模板方式)
*
* @param fileName 文件名
* @param response 响应对象
* @param data 数据集
* @param clazz 实体类模板
* @param excludeColumnFieldNames 忽略指定列导出根据字段名
* @param <T> 泛型
*/
public static <T> void export(String fileName, HttpServletResponse response, List<T> data, Class<T> clazz, List<String> excludeColumnFieldNames) throws IOException {
exportPublic(fileName, response, data, clazz, excludeColumnFieldNames);
}
/**
* export公共
*
* @param fileName 文件名
* @param response 响应对象
* @param data 数据集
* @param clazz 实体类模板
* @param excludeColumnFieldNames 忽略指定列导出根据字段名
* @param <T> 泛型
* @throws IOException
*/
private static <T> void exportPublic(String fileName, HttpServletResponse response, List<T> data, Class<T> clazz, List<String> excludeColumnFieldNames) throws IOException {
setResponse(response, fileName);
//导出
EasyExcel.write(response.getOutputStream(), clazz)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(defaultStylePolicyPolicy())
// .registerWriteHandler(new CustomCellWriteHeightConfig())
.sheet()
.doWrite(data);
}
/**
* EasyExce导出到浏览器(动态标题(字段)方式)
*
* @param fileName 文件名
* @param response 响应对象
* @param heads 标题(字段)
* @param data 数据
* @throws IOException
*/
public static void export(String fileName, HttpServletResponse response, List<List<String>> heads, List<List<Object>> data) throws IOException {
setResponse(response, fileName);
//导出
EasyExcel.write(response.getOutputStream())
.head(heads)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(defaultStylePolicyPolicy())
.sheet()
.doWrite(data);
}
/**
* 导出失败返回错误模板
*
* @param response 响应对象
* @param pathName 模板路径
* @param msg 异常消息
* @throws IOException
*/
public static void exportError(HttpServletResponse response, String pathName, String msg) throws IOException {
setResponse(response, "导出失败");
InputStream resourceAsStream = EasyExcelUtils.class.getResourceAsStream(pathName);
Map<String, String> map = new HashMap<>();
map.put("msg", msg);
//导出
EasyExcel.write(response.getOutputStream()).withTemplate(resourceAsStream).sheet().doFill(map);
}
/**
* 设置响应对象
*
* @param response
* @param fileName
*/
private static void setResponse(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20") + ".xlsx");
}
/**
* 获取标题和数据
* 标题 listTitle
* 数据 listBody
*
* @param file 文件
* @return 返回包含标题和数据的Map
* @throws IOException 当发生I/O错误时抛出
*/
public static Map<String, Object> readExcelTitleAndBody(MultipartFile file) throws IOException {
InputStream inputStream = file.getInputStream();
List<String> listTitle = new ArrayList<>(4);
List<Map<String, String>> listBody = new ArrayList<>();
Integer count = 0;
AnalysisEventListener<Map<Integer, String>> listener = new AnalysisEventListener<Map<Integer, String>>() {
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
// 在这里处理标题行的数据
// headMap是一个Map,键为列的索引,值为列的标题
// 你可以在这里获取到标题行的数据
if (listTitle.size() == 0) {
headMap.forEach((k, v) -> {
listTitle.add(v);
});
}
}
@Override
public void invoke(Map<Integer, String> data, AnalysisContext context) {
// 这里是读取到每一行数据时的处理逻辑
Map<String, String> map = new HashMap<>();
data.forEach((k, v) -> {
map.put(listTitle.get(k), v);
});
listBody.add(map);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 读取完成后的处理逻辑
}
};
EasyExcel.read(inputStream, listener).sheet().doRead();
inputStream.close();
Map<String, Object> resMap = new HashMap<>();
resMap.put("listTitle", listTitle);
resMap.put("listBody", listBody);
// 返回标题行的数据
return resMap;
}
/**
* 默认样式策略策略
*
* @return
*/
public static HorizontalCellStyleStrategy defaultStylePolicyPolicy() {
// 头的策略
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
//设置列宽
// 背景设置为浅蓝色
headWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
//设置水平对齐方式
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
//设置字体为微软雅黑
WriteFont headWriteFont = new WriteFont();
headWriteFont.setFontName("宋体");
headWriteCellStyle.setWriteFont(headWriteFont);
// 内容的策略
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
//设置字体为微软雅黑
WriteFont contentWriteFont = new WriteFont();
contentWriteFont.setFontName("宋体");
contentWriteCellStyle.setWriteFont(contentWriteFont);
// 这个策略是 头是头的样式 内容是内容的样式
return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
}
/**
* 通用xlsx模板下载
*
* @param response
* @param fileName
*/
public static void templateDownload(HttpServletResponse response, String fileName) {
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
response.setContentType("multipart/form-data");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
try {
InputStream inputStream = EasyExcelUtils.class.getResourceAsStream("/static/template/" + fileName);
if (inputStream == null) {
return;
}
OutputStream os = response.getOutputStream();
byte[] b = new byte[2048];
int length;
while ((length = inputStream.read(b)) > 0) {
os.write(b, 0, length);
}
os.close();
inputStream.close();
} catch (IOException e) {
log.error(e.getMessage());
}
}
}
package com.yonde.dcs.plan.common.vo;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.apache.poi.ss.usermodel.CellType;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@EqualsAndHashCode(callSuper = false)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExtPuchasePlanExcelVO {
@ExcelProperty(value = {"采购计划","操作*"},index = 0)
@ColumnWidth(20)
private String operation;
/**
* 外协项目名称
*/
@ExcelProperty(value = {"采购计划","外协(外购)项目名称*"},index = 1)
@ColumnWidth(20)
private String outsourceProjectName;
/**
* 采购技术文件实际提交时间
*/
@ExcelProperty(value = {"采购计划","采购技术文件提交时间*"},index = 2)
@ColumnWidth(20)
private LocalDateTime purDesignFileSubmitTime;
/**
* 合同签订时间*
*/
@ExcelProperty(value = {"采购计划","合同签订时间*"},index = 3)
@ColumnWidth(20)
private LocalDateTime contractActualSigningTime;
/**
* 合同交付时间*
*/
@ExcelProperty(value = {"采购计划","合同交付时间*"},index = 4)
@ColumnWidth(20)
private String contractActualDeliveryTime;
/**
* 采购技术文件负责人
*/
@ExcelProperty(value = {"采购计划","采购技术文件负责人*"},index = 5)
@ColumnWidth(20)
private String purDesignFileManager;
/**
* 采购预算
*/
@ExcelProperty(value = {"采购计划","预算(万元)*"},index = 6)
@ColumnWidth(20)
private String purchaseBudget;
/**
* 项目代号
*/
@ExcelProperty(value = {"采购计划","项目代号*"},index = 7)
@ColumnWidth(20)
private String projectCode;
/**
* 密级
*/
@ExcelProperty(value = {"采购计划","密级*"},index = 8)
@ColumnWidth(20)
private String secretCode;
/**
* 备注
*/
@ExcelProperty(value = {"采购计划","备注*"},index = 9)
@ColumnWidth(20)
private String note;
public static void main(String[] args) {
List<ExtPuchasePlanExcelVO> list = new ArrayList<>();
for (int i=0;i<=1;i++){
ExtPuchasePlanExcelVO extPuchasePlanExcelVO = new ExtPuchasePlanExcelVO();
extPuchasePlanExcelVO.setNote("测试"+i);
list.add(extPuchasePlanExcelVO);
}
EasyExcel.write(
"F:\\yangyi\\项目\\清华核研院\\核研院设计文档及原型\\采购计划导入模板.xlsx", ExtPuchasePlanExcelVO.class)
.sheet("采购计划").doWrite(list);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment