1. easyexcel–100M
EasyExcel是一个基于Java的使用简单、节省内存的读写Excel的开源项目。在尽大概节省内存的环境下支持读写百M的Excel。
节省内存的原因:在剖析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个剖析
EasyExcel接纳一行一行的剖析模式,并将一行的剖析结果以观察者的模式通知处理惩罚
通过Java代码完成对Excel的读写操作。所谓的读写理解为上传和下载
github地点:https://github.com/alibaba/easyexcel
官方文档:https://www.yuque.com/easyexcel/doc
2. easyexcel写操作
所谓的写操作,就是把Java中的类对象写入到excel表格中
实现步调
- <dependency>
- <groupId>repMaven.com.alibaba</groupId>
- <artifactId>easyexcel</artifactId>
- <version>3.0.5</version>
- </dependency>
复制代码
- 封装相应的对象,创建与表格对应的实体类
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- public class ExcelDemo {
- @ExcelProperty(value = "姓名")//标记excel的表头内容
- public String name;
- @ExcelProperty(value = "年龄")
- public Integer age;
- @ExcelProperty(value = "性别")
- public String sex;
- @ExcelIgnore//写入excel表格时忽略该属性
- public String address;
- }
复制代码
- @ExcelProperty:标志excel的表头内容
- @ExcelIgnore:在写入excel表格时忽略该属性
- 通过easyexcel完成写入操作
- public class WriteExcel {
- public static void main(String[] args) {
- //fileName:表示excel写入的路径以及名称
- String fileName="D:\\idea\\easyexcel_demo1\\writer.xlsx";
- //这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板,然后文件流会自动关闭
- //如果这里使用03,则 传入 excelType 参数即可
- List<ExcelDemo> list=new ArrayList<>();
- list.add(new ExcelDemo("章三",18,"男","郑州"));
- list.add(new ExcelDemo("李斯",19,"男","郑州"));
- list.add(new ExcelDemo("汪芜",20,"女","郑州"));
- list.add(new ExcelDemo("码字",25,"男","郑州"));
- EasyExcel.write(fileName,ExcelDemo.class).sheet("第一次完成写操作").doWrite(list);
- }
- }
复制代码
3. easyexcel写操作——web模式【导出】
导出:必要将数据库内里的文件以附件的形式下载到本地电脑,必要参数为response对象,返回值类型为void
- @Controller
- public class ExcelController {
- @GetMapping("download")
- public void download(HttpServletResponse response) throws IOException {
- // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
- response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
- response.setCharacterEncoding("utf-8");
- // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
- String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
- response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
- List<ExcelDemo> list=new ArrayList<>();
- list.add(new ExcelDemo("章三",18,"男","郑州"));
- list.add(new ExcelDemo("李斯",19,"男","郑州"));
- list.add(new ExcelDemo("汪芜",20,"女","郑州"));
- list.add(new ExcelDemo("码字",25,"男","郑州"));
- EasyExcel.write(response.getOutputStream(), ExcelDemo.class).sheet("模板").doWrite(list);
- }
- }
复制代码 也可以在controllre层仅进行调用操作,将逻辑交由service去做,即:
- @ApiOperation("导出")
- @GetMapping("/download")
- public void exportData(HttpServletResponse response){
- dictService.exportData(response);
- }
复制代码
- @Override
- public void exportData(HttpServletResponse response) {
- try {
- //设置相关参数
- response.setContentType("application/vnd.ms-excel");
- response.setCharacterEncoding("utf-8");
- // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
- String fileName = URLEncoder.encode("数据字典", "UTF-8");
- response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
- //获取文件
- List<Dict> list = this.baseMapper.selectList(null);
- //转换文件
- ArrayList<DictEeVo> dictEeVos = new ArrayList<>();
- for (Dict dict : list) {
- DictEeVo dictEeVo = new DictEeVo();
- //转换
- BeanUtils.copyProperties(dict, dictEeVo);
- //添加
- dictEeVos.add(dictEeVo);
- }
- //写出
- EasyExcel.write(response.getOutputStream(), DictEeVo.class).sheet("数据字典").doWrite(dictEeVos);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
复制代码 测试
测试仅需答应项目,然后在前端页面写入现实的url地点即可,也可以添加按钮的点击事件进行测试
4. easyexcel读操作
- 引入fastjson依靠
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.83</version>
- </dependency>
复制代码 com.alibaba.fastjson.JSON是阿里巴巴开源的一个高性能数据交换格式库,它是基于Java语言的JSON剖析和生成工具。Fastjson旨在提供一种快速、便捷的方式来序列化和反序列化Java对象到JSON字符串,以及将JSON字符串转换回Java对象。它支持大数据量的处理惩罚,而且具有优秀的性能,通常比尺度的Java自带的java.util.JSONObject和org.json.JSONObject更快。
使用Fastjson的好处包括:
- 高效:通过字节码操作,使得JSON剖析和生成的速度非常快。
- 易用:API设计简洁明了,易于理解和上手。
- 功能丰富:支持复杂数据结构的处理惩罚,如日期、数组、聚集等。
在Java项目中,你可以通过Maven或Gradle添加fastjson依靠来使用它,然后通过JSONObject、JSONArray或其他类来进行JSON相关的操作。
- 创建监听器
- package com.zmq.excel;
- import com.alibaba.excel.context.AnalysisContext;
- import com.alibaba.excel.read.listener.ReadListener;
- import com.alibaba.excel.util.ListUtils;
- import com.alibaba.fastjson.JSON;
- import lombok.extern.slf4j.Slf4j;
- import java.util.List;
- // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
- @Slf4j
- public class DemoDataListener implements ReadListener<ExcelDemo> {
- /**
- * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
- */
- private static final int BATCH_COUNT = 100;
- /**
- * 缓存的数据
- */
- private List<ExcelDemo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
- /**
- * 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
- */
- private DemoDAO demoDAO;
- public DemoDataListener() {
- // 这里是demo,所以随便new一个。实际使用如果到了spring,请使用下面的有参构造函数
- demoDAO = new DemoDAO();
- }
- /**
- * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
- *
- * @param demoDAO
- */
- public DemoDataListener(DemoDAO demoDAO) {
- this.demoDAO = demoDAO;
- }
- /**
- * 这个每一条数据解析都会来调用
- *
- * @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
- * @param context
- */
- //一行一行的去读取里面的数据
- @Override
- public void invoke(ExcelDemo data, AnalysisContext context) {
- log.info("解析到一条数据:{}", JSON.toJSONString(data));
- cachedDataList.add(data);
- // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
- if (cachedDataList.size() >= BATCH_COUNT) {
- saveData();
- // 存储完成清理 list
- cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
- }
- }
- /**
- * 所有数据解析完成了 都会来调用
- *
- * @param context
- */
- @Override
- public void doAfterAllAnalysed(AnalysisContext context) {
- // 这里也要保存数据,确保最后遗留的数据也存储到数据库
- saveData();
- log.info("所有数据解析完成!");
- }
- /**
- * 加上存储数据库
- */
- private void saveData() {
- log.info("{}条数据,开始存储数据库!", cachedDataList.size());
- demoDAO.save(cachedDataList);
- log.info("存储数据库成功!");
- }
- }
复制代码 进行读操作时就会触发监听器,基本不必要改动
- dao
- package com.zmq.excel;
- import java.util.List;
- /**
- * 假设这个是你的DAO存储。当然还要这个类让spring管理,当然你不用需要存储,也不需要这个类。
- **/
- public class DemoDAO {
- public void save(List<ExcelDemo> list) {
- // 如果是mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
- }
- }
复制代码 dao中填写必要的操作
- 读取
- public class ReadExcel {
- public static void main(String[] args) {
- /**
- * 指定列的下标或者列名
- *
- * <p>1. 创建excel对应的实体对象,并使用{@link ExcelProperty}注解. 参照{@link IndexOrNameData}
- * <p>2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link IndexOrNameDataListener}
- * <p>3. 直接读即可
- */
- //fileName:表示excel读取的路径以及名称
- String fileName="D:\\idea\\easyexcel_demo1\\writer.xlsx";
- // 这里默认读取第一个sheet
- //new DemoDataListener():监听器
- EasyExcel.read(fileName, ExcelDemo.class, new DemoDataListener()).sheet().doRead();
- }
- }
复制代码 5. easyexcel文件上传-web【导入】
导入:必要将本地文件插入到数据库,参数:multiparefile,返回值:“成功或失败”
使用excel进行导入必要剖析器的共同,使用监听器对读取的文件进行操作
剖析器:用来读取文件,并将数据插入到数据库
- 参加文件上传的依靠
- <dependency>
- <groupId>repMaven.commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- <version>1.4</version>
- </dependency>
复制代码 commons-fileupload是一个开源库,专为Java应用程序设计,用于处理惩罚文件上传功能。它简化了处理惩罚HTTP哀求中的multipart/form-data格式,这种格式通常用于用户通过Web表单上传文件到服务器。该库提供了一组工具类和处理惩罚器,使得开辟者能够剖析上传的文件流,并管理文件名、大小限制等复杂操作。它的API易于使用,支持断点续传以及错误处理惩罚,广泛应用于web应用开辟中的文件上传组件。
- 文件上传剖析器——spring设置文件中
若使用springboot框架,仅引入上述依靠即可
- <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
- <property name="maxUploadSize" value="1000000000"/>
- </bean>
复制代码 - controller
- @Autowired
- private DemoDAO demoDAO;
- @PostMapping("/upload")
- @ResponseBody //将返回值转化为json格式
- public String upload(MultipartFile file) throws IOException{
- EasyExcel.read(file.getInputStream(), ExcelDemo.class, new DemoDataListener(demoDAO)).sheet().doRead();
- return "success";
- }
复制代码 DemoDao层参加注入spring容器的注解:@Component
- 测试——使用postman完成测试
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |