文件上传下载、Excel导入导出

主要内容

  • 文件上传 重点

  • 文件下载 重点

  • 生成 Excel 重点

  • 解析 Excel 重点

  • Excel 导入导出 重点

章节目标

  • 掌握文件上传

  • 掌握文件下载

  • 掌握Excel 生成与解析

  • 掌握Excel 导入导出

第一节 文件上传和下载

1. 文件处理的包

commons-io.jar 封装了常用的 IO 的相关操作,提供了 IOUtils 工具类供开发人员使用

commons-fileupload.jar 文件上传的处理包,因为文件上传也会涉及到 IO 操作,因此,该包需要配合commons-io.jar 使用。

  • FileItemFactory 文件项工厂,主要提供创建文件项的功能

  • DiskFileItemFactory 磁盘文件项工厂,主要用于解析上传文件时,创建对应的文件项

  • ServletFileUpload Servlet 文件上传对象,主要用于判断请求是否是文件上传请求,以及请求中的内容解析。解析时需要使用文件项工厂来创建文件项

2. 文件上传

2.1 form 表单上传
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

  
    文件上传和下载
  
  
    
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;


@WebServlet("/upload")
public class UploadServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        if (!ServletFileUpload.isMultipartContent(req)) {
            throw new RuntimeException("未发现multipart/form-data");
        }
        FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        //文件上传的头部信息编码格式为UTF-8
        upload.setHeaderEncoding("UTF-8");
        //文件上传的最大大小为50M
        upload.setSizeMax(1024 * 1024 * 50);
        //单个文件最大大小为5M
        upload.setFileSizeMax(1024 * 1024 * 5);
        boolean success = true;
        try {
            //解析请求,得到form表单上传的每一个与文件相关的项
            List fileItems = upload.parseRequest(req);
            for (FileItem item : fileItems) {
                if (item.isFormField()) {//如果是表单字段
                    System.out.println(item.getFieldName());
                } else {
                    File parent = new File("d:/upload");
                    if (!parent.exists()) {
                        parent.mkdirs();
                    }
                    File file = new File(parent, item.getName());
                    InputStream is = item.getInputStream();
                    OutputStream os = new FileOutputStream(file);
                    //使用commons-io包提供的工具类,将输入流中的信息拷贝至输出流,也就是写入文件
                    IOUtils.copy(item.getInputStream(), os);
                    //关闭输入流
                    IOUtils.closeQuietly(is);
                    //关闭输出流
                    IOUtils.closeQuietly(os);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            success = false;
        }
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print(success ? "上传成功" : "上传失败");
        writer.flush();
        writer.close();
    }
}
2.2 ajax 文件上传
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    文件上传和下载







3. 文件下载

下载
import org.apache.commons.io.IOUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@WebServlet("/download")
public class DownloadServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");//获取下载的文件名
        File file = new File("d:/upload", name);//定位下载的文件
        byte[] data = name.getBytes(StandardCharsets.UTF_8);//获取下载的文件名的字节数据
        //转换编码格式,重新构建字符串,因为浏览器默认支持的编码是ISO_8859_1,因此,要转换为这种编码下中文才能正常显示
        name = new String(data, StandardCharsets.ISO_8859_1);
        //设置内容处理方案:以附件的形式处理
        resp.setHeader("Content-Disposition", "attachment;filename="+name);
        OutputStream os = resp.getOutputStream();
        InputStream is = new FileInputStream(file);
        IOUtils.copy(is, os);
        IOUtils.closeQuietly(is);
        IOUtils.closeQuietly(os);
    }
}

第二节 Excel 处理

1. EasyExcel 介绍

EasyExcel 是阿里巴巴开源的一个 Excel 处理框架,以使用简单、节省内存著称。EasyExcel 能大大减少占用内存的主要原因是在解析 Excel 时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

2. EasyExcel 生成 Excel

import com.alibaba.excel.annotation.ExcelProperty;

public class User {
    //ExcelProperty表示在生成的Excel表格中的属性,value表示该属性对应的表头名称, index表示该属性所处的列的位置
    @ExcelProperty(value = "账号", index = 0)
    private String username;

    @ExcelProperty(value = "密码", index = 1)
    private String password;

    @ExcelProperty(value = "姓名", index = 2)
    private String name;

    @ExcelProperty(value = "性别", index = 3)
    private String sex;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
    
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

public class ExcelUtil {

    public static void main(String[] args) {
        String excelName = "d:/excel/用户信息.xlsx";
        List users = new ArrayList<>();
        for(int i=0; i<10; i++){
            User user = new User();
            user.setUsername("admin" + i);
            user.setPassword("test"+i);
            user.setName("测试"+i);
            user.setSex( i% 3==0 ? "男" : "女");
            users.add(user);
        }
        EasyExcel.write(excelName, User.class)
                .sheet("用户信息表")
                .doWrite(users);
    }
}

工具类方法封装

import com.alibaba.excel.EasyExcel;
import com.qf.jsp.pojo.User;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

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

public class ExcelUtil {

    public static void main(String[] args) {
        List users = new ArrayList<>();
        for(int i=0; i<10; i++){
            User user = new User();
            user.setUsername("admin" + i);
            user.setPassword("test"+i);
            user.setName("测试"+i);
            user.setSex( i% 3==0 ? "男" : "女");
            users.add(user);
        }
        generateExcel("d:/excel/用户信息.xlsx", "用户信息列表", User.class, users);
    }

    /**
     * 生成 Excel
     * @param path Excel 存储路径
     * @param sheetName sheet名称
     * @param clazz 存储的数据类型
     * @param dataList 存储的数据
     * @param 
     */
    public static  void generateExcel(String path, String sheetName, Class clazz, List dataList){
        EasyExcel.write(path, clazz).sheet(sheetName).doWrite(dataList);
    }
}

3. EasyExcel 解析 Excel

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.qf.jsp.pojo.User;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

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

public class ExcelUtil {

    public static void main(String[] args) {
        String excelName = "d:/excel/用户信息.xlsx";
        //读取监听器,每一行读取动作都会被监听
        ReadListener listener = new ReadListener() {

            @Override
            public void invoke(User user, AnalysisContext analysisContext) {
                System.out.println(user.toString());
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                System.out.println("读取完成");
            }
        };
        //读取给定的Excel,读取的内容转换为User类型的对象,读取时使用listener进行监听
        //sheet()方法表示读取所有的sheet
        //doRead() 表示表示执行读取动作
        EasyExcel.read(excelName,User.class, listener).sheet().doRead();
    }

    /**
     * 生成 Excel
     * @param path Excel 存储路径
     * @param sheetName sheet名称
     * @param clazz 存储的数据类型
     * @param dataList 存储的数据
     * @param 
     */
    public static  void generateExcel(String path, String sheetName, Class clazz, List dataList){
        EasyExcel.write(path, clazz).sheet(sheetName).doWrite(dataList);
    }
}

工具类方法封装

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;

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

public class ExcelReadLister implements ReadListener {

    private List dataList = new ArrayList<>();

    @Override
    public void invoke(T data, AnalysisContext context) {
        dataList.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        System.out.println("Excel 读取完毕");
    }

    public List getDataList(){
        return dataList;
    }
}

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.qf.jsp.pojo.User;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

public class ExcelUtil {

    public static void main(String[] args) {
        String excelName = "d:/excel/用户信息.xlsx";
        List users = parseExcel(excelName, User.class);
        users.forEach(System.out::println);
    }

    /**
     * 解析Excel
     * @param excelName 解析的Excel的路径
     * @param 
     * @return
     */
    public static  List parseExcel(String excelName, Class clazz){
        ExcelReadLister lister = new ExcelReadLister<>();
        //读取给定的Excel,读取的内容转换为User类型的对象,读取时使用listener进行监听
        //sheet()方法表示读取所有的sheet
        //doRead() 表示表示执行读取动作
        EasyExcel.read(excelName, clazz, lister).sheet().doRead();
        return lister.getDataList();
    }
    /**
     * 生成 Excel
     * @param path Excel 存储路径
     * @param sheetName sheet名称
     * @param clazz 存储的数据类型
     * @param dataList 存储的数据
     * @param 
     */
    public static  void generateExcel(String path, String sheetName, Class clazz, List dataList){
        EasyExcel.write(path, clazz).sheet(sheetName).doWrite(dataList);
    }
}

4. EasyExcel导入导出

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.qf.jsp.pojo.User;

import java.io.*;
import java.util.List;

public class ExcelUtil {

    private static final int MAX_COUNT_PER_SHEET = 5000;

    public static void main(String[] args) throws IOException {
        String excelName = "d:/excel/用户信息.xlsx";
        List users = parseExcel(excelName, User.class);
        export("用户信息表", new FileOutputStream("d:/excel/test.xlsx"), User.class, users);
    }

    /**
     * 解析Excel
     * @param excelName 解析的Excel的路径
     * @param 
     * @return
     */
    public static  List parseExcel(String excelName, Class clazz){
        ExcelReadLister lister = new ExcelReadLister<>();
        //读取给定的Excel,读取的内容转换为User类型的对象,读取时使用listener进行监听
        //sheet()方法表示读取所有的sheet
        //doRead() 表示表示执行读取动作
        EasyExcel.read(excelName, clazz, lister).sheet().doRead();
        return lister.getDataList();
    }
    /**
     * 生成 Excel
     * @param path Excel 存储路径
     * @param sheetName sheet名称
     * @param clazz 存储的数据类型
     * @param dataList 存储的数据
     * @param 
     */
    public static  void generateExcel(String path, String sheetName, Class clazz, List dataList){
        EasyExcel.write(path, clazz).sheet(sheetName).doWrite(dataList);
    }

    public static  List importExcel(InputStream is, Class clazz){
        ExcelReadLister lister = new ExcelReadLister<>();
        //读取给定的Excel,读取的内容转换为User类型的对象,读取时使用listener进行监听
        //sheet()方法表示读取所有的sheet
        //doRead() 表示表示执行读取动作
        EasyExcel.read(is, clazz, lister).sheet().doRead();
        return lister.getDataList();
    }

    public static  void export(String sheetName, OutputStream os, Class clazz, List dataList) throws IOException {
        ExcelWriterBuilder builder = EasyExcel.write(os, clazz);
        ExcelWriter writer = builder.build();
        int sheetCount = dataList.size() / MAX_COUNT_PER_SHEET;
        if(dataList.size() % MAX_COUNT_PER_SHEET > 0){
            sheetCount += 1;
        }
        for(int i=0; i dataList.size() - 1){
                end = dataList.size() - 1;
            }
            writer.write(dataList.subList(start, end), sheet);
        }
        writer.finish();
        os.close();
    }
}

第三节  easy excel 详解

Easy Excel是一种功能强大的Excel操作工具,它可以帮助用户轻松进行Excel文件的导入和导出操作。下面是关于Easy Excel导入导出的详细解释:

1. 导入Excel文件:

   a. 首先,需要创建一个Java类,用于定义Excel文件中的数据结构,比如一个实体类。
   b. 在这个类中,使用Easy Excel提供的注解来标记Excel文件中的每个字段,以便正确地读取Excel数据。
   c. 使用Easy Excel的`EasyExcel.read()`方法读取Excel文件,并将其转换为Java对象。
   d. 通过遍历Java对象,可以访问Excel文件中的每个数据,并进行相应的操作。

2. 导出Excel文件:

   a. 首先,需要创建一个Java类,用于定义要导出的数据结构,比如一个实体类。
   b. 在这个类中,使用Easy Excel提供的注解来标记每个字段,以便正确地导出数据到Excel文件。
   c. 使用Easy Excel的`EasyExcel.write()`方法创建一个Excel文件,并将Java对象写入文件中。
   d. 通过遍历Java对象,可以将数据写入Excel文件的每个单元格。

Easy Excel还提供了其他一些功能,比如读取和写入多个Sheet、自定义导入导出逻辑、处理大数据量等。它还支持更多的Excel操作,比如读取和写入Excel的样式、合并单元格等。

总之,Easy Excel是一个方便、高效的Excel操作工具,能够帮助用户轻松实现Excel文件的导入和导出操作。更详细的可以去看easy excel的官方文档,上面有更详细的解释说明。

你可能感兴趣的:(excel)