前台页面

  • type=“file”,这个当然是必须的。
  • accept,这一项可以让你的输入文件只可以选择 excel 的三种文件名,确保在前台对文件进行过滤。
  • form表单不要忘记加上 enctype=“multipart/form-data”
<form action="#" method="post" enctype="multipart/form-data">
	<input type="file" name="excelFile" checked accept=".csv, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
</form>

读取excel (Servlet层)

  1. 利用FileItem便利request请求传来的参数,for循环每次进行判断,可以输出request的请求是否为文本,fileItem.isFormField()方法
  2. 创建出一个文件对象,这里给file设置了一个临时的位置,可以随意指定,最后都会删除。
  3. fileItem.write(file),把request上传的文件写入到定义的File文件中,进行下一步Excel的操作。

ExcelUtils.readAndsaveExcelFile(path,username,updateTime);
这个工具类是我自己定义的,下面是具体代码

List<FileItem> list = servletFileUpload.parseRequest(request);
for (FileItem fileItem : list) {
    if (fileItem.isFormField()) {
        System.out.println(fileItem.getFieldName());
        System.out.println(fileItem.getString("UTF-8"));
    } else {
        String path = "D:\\temp.xlsx";
        File file = new File(path);
        fileItem.write(file);
        ExcelUtils.readAndsaveExcelFile(path,username,updateTime);
        file.delete(); // 操作完后,删除excel文件
    }
}

ExcelUtils 工具类

这里主要是EasyExcel的read方法,其中有三个参数,第一个是文件的路径,第二个是定义好的Bean的class,第三个是一个Excel监听器,这个也是自己定义的。

import com.alibaba.excel.EasyExcel;
import com.jyuxuan.bean.Postcard;


import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * excel工具类
 */
public class ExcelUtils {

    /**
     * 读取excel,保存数据库
     *
     * @param path
     * @return
     */
    public static void readAndsaveExcelFile(String path, String username, String updateTime) {
        EasyExcel.read(path, Postcard.class, new ExcelListener(username, updateTime)).sheet().doRead();
    }

    /**
     * 写入excel,保存文件
     *
     * @param path
     * @param postcards
     */
    public static void writeExcelFile(String path, List<Postcard> postcards) {
        Set<String> excludeColumnFiledNames = new HashSet<String>();
        EasyExcel.write(path, Postcard.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet("模板").doWrite(postcards);
    }
}

ExcelListener

  1. BATCH_COUNT 是一个次数,当excel操作多少到多少数据的时候,把这些数据进行后续的操作,不满BATCH_COUNT 的时候直接结束,这样可以有效防止OOM的发生,根据阿里的程序猿统计,可以设置3000都没问题。
  2. 由于自己的数据是封装成类的,多条excel数据对应着多条自己的数据,使用List来保存。
  3. 可以在这个类中加入操作数据库的dao层变量,也可以为这个类设置自己的私有变量,这里我设置了username和updateTime两条。

其中函数的具体用途写在了程序注释中

package com.jyuxuan.utils.excel;

import java.util.ArrayList;
import java.util.List;

import com.jyuxuan.bean.Postcard;
import com.jyuxuan.dao.IPostcardDao;
import com.jyuxuan.dao.Impl.PostcardDao;


import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

/**
 * excel写入监听器
 */
public class ExcelListener extends AnalysisEventListener<Postcard> {

    private static final int BATCH_COUNT = 100; // 防止OOM,进行多少次进行一次保存,防止内存溢出

    ArrayList<Postcard> postcards = new ArrayList<Postcard>(); // 保存的数据

    private IPostcardDao postcardDao = new PostcardDao(); // 操作数据库

    private String username;

    private String updateTime;

    public ExcelListener() {
    }

    public ExcelListener(String username, String updateTime) {
        this.username = username;
        this.updateTime = updateTime;
    }

    /**
     * 读取excel
     *
     * @param postcard
     * @param context
     */
    @Override
    public void invoke(Postcard postcard, AnalysisContext context) {
        System.out.println("解析到一条数据" + postcard.toString());
        postcard.setUsername(this.username);
        postcard.setUpdateTime(this.updateTime);
        postcards.add(postcard);
        if (postcards.size() >= BATCH_COUNT) {
            saveData();
            postcards.clear();
        }
    }

    /**
     * 读取数据之后进行的操作
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
        System.out.println("所有数据解析完成!");
    }

    /**
     * 保存数据库
     */
    private void saveData() {
        System.out.println("{" + String.valueOf(postcards.size()) + "}条数据,开始存储数据库!");
        postcardDao.insert(postcards);
        System.out.println("存储数据库成功!");
    }


}

写入数据

第一个参数是路径,第二个参数是类的class,第三个参数可以指定不包括的列,也可以指定包括的列,使用includeColumnFiledNames就可以。

	/**
     * 写入excel,保存文件
     *
     * @param path
     * @param postcards
     */
    public static void writeExcelFile(String path, List<Postcard> postcards) {
        Set<String> excludeColumnFiledNames = new HashSet<String>();
        EasyExcel.write(path, Postcard.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet("模板").doWrite(postcards);
    }

强烈建议取github上看官方文档,非常清楚。

GitHub 加速计划 / ea / easyexcel
14
5
下载
快速、简洁、解决大文件内存溢出的java处理Excel工具
最近提交(Master分支:4 个月前 )
c42183df Bugfix 4 个月前
efa7dff6 * 重新加回 `commons-io` 4 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐