文件的上传
所需要的jar包:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
YML文件中的配置:
Spring:
servlet:
multipart:
max-request-size: 10M
max-file-size: 10M
corrosion:
url: 请求路径
service
@Service
public class Dom{
private final String ID_NAME = "编号";
@Value("${corrosion.url}")
private String url;
@Override
public T importFile(MultipartFile file) throws Exception {
T respM01 = new T();
ArrayList<DomF04RespS01> list = new ArrayList<>();
String oldfilename = serviceFile.getOriginalFilename();//旧的文件名
String substring = oldfilename.substring(oldfilename.lastIndexOf("."));
String documentname = oldfilename.split(substring )[0];
String replaceAll = UUID.randomUUID().toString().replaceAll("_", "");//UUID
String newfilename = documentname + "SMDM" + replaceAll + substring; //新的文件名
//这里的SMDM(神秘代码)没有任何意义,只是为了下载的时候好处理文件名
String savePath = url + newfilename;//文件路径
File file = new File(savePath);
//判断保存地址的文件夹是否存在,不存在就新建
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
//这里是一个内部类监听,可以拿出来单独写一份。监听用来处理数据
AnalysisEventListener<K> eventListener = new AnalysisEventListener<>() {
private final Logger log =
LoggerFactory.getLogger(AnalysisEventListener.class);
@Override
public void invoke(K k, AnalysisContext analysisContext) {
//这里边就是你要处理的数据,因情况而定
//k就是你要处理的数据
if(k.getId() != null){
list.add(k);
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
};
InputStream in = serviceFile.getInputStream();
EasyExcel.read(in, K.class, eventListener).sheet().doRead();
respM01.setDemoList(list);
//别忘记关闭
in.close();
return respM01;
}
}
这里有一个小知识点,文件名命名的时候最好不要出现这些符号。一是没有意义,二是处理也不方便,具体还是看这位大佬的博客
http请求中对特殊字符的处理_forwardMyLife的博客-优快云博客_http特殊字符
实体类
@Data
public class dom implements Serializable{
private static final long serialVersionUID = 1495675280489558317L;
/**
* 编号
*/
@ExcelProperty(value = "编号",index = 0)
private String id;
/**
* 阶段及任务
*/
@ExcelProperty(value = "阶段及任务",index = 1)
private String stage;
/**
* 工时
*/
@ExcelProperty(value = "工时",index = 2)
private String workingHours;
/**
* 备注
*/
@ExcelProperty(value = "备注",index = 3)
private String remarks;
}
实体类中的数据要对应到你的表格中去,尽量按循序来
@ExcelProperty(value = "对应到表格中的文字",index = 表格的位置)
如果你是按照循序来的,你大可以不需要index
文件的下载
collection
@ApiOperation("文件下载")
@GetMapping("/bom/download")
public T download(String path,HttpServletResponse response) throws Exception {
//这里我把response和path封装了起来
//我在往业务层传递的时候response老是传递不过去
T ReqtM01 = new T();
ReqtM01.setPath(path);
ReqtM01.setResponse(response);
return domDownload.dom(ReqtM01);
}
业务层
@Service
public class dom{
@Value("${corrosion.url}")
private String url;
private final Integer RETURN_CODE = 200;
@Override
public Integer execute(T t) throws Exception {
String oldfilename = t.getPath()
String path = url + oldfilename;//文件路径
HttpServletResponse response = t.getResponse();
// 设置response的Header
response.setCharacterEncoding("UTF-8");
// 下载的文件的路径(绝对路径)
File file = new File(path);
// 获取文件名
String filename = file.getName();
// 获取文件的后缀名
String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
//新的名字
String newfilename = filename.split("SMDM")[0] + "." + ext;
// 将文件写入输入流
FileInputStream fileInputStream = new FileInputStream(file);
InputStream fis = new BufferedInputStream(fileInputStream);
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(newfilename, "UTF-8"));
// 告知浏览器文件的大小
response.addHeader("Content-Length", "" + file.length());
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
outputStream.write(buffer);
outputStream.flush();
return RETURN_CODE;
}
}
文件下载使用postman时要注意,中文名会乱码所以测试下载的时候最好还是使用浏览器测试
也可能是因为我操作不当才导致postman中文乱码问题,具体问题还是要自行百度
监听
public class ExcelListener extends AnalysisEventListener<> {
private final Logger log = LoggerFactory.getLogger(ExcelListener.class);
private static final int BATCH_COUNT = 5;
private List<T> datas = Lists.newArrayList();
@Override
public void invoke(T t, AnalysisContext analysisContext) {
log.info("解析到一条数据:{}", JSON.toJSONString(t));
//数据存储到list,
datas.add(t);
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
saveData();
// 存储完成清理 list
datas.clear();
if (datas.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
datas.clear();
}
//要是想一次性取出数据,注解掉这一块代码自己写处理逻辑
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();
LOGGER.info("所有数据解析完成!");
}
/**
* 入库
*/
private void saveData() {
log.info("{}条数据,开始存储数据库!", datas.size());
//这个方法自己实现 能完成保存数据入库即可
//demoDAO.save(datas);
LOGGER.info("存储数据库成功!");
}
public List<DomF04RespS01> getDatas() {
return datas;
}
public void setDatas(List<DomF04RespS01> datas) {
this.datas = datas;
}
}
小白见解,有需要优化或者不对的地方还请大家不吝赐教