因为实际开发中很多需求都需要实现Excel批量导入和导出,所以今天就来写一个后端demo实现Excel的导入和导出。
需求:
Excel的导入
1对文件路径为D:\Users\Mixi\IdeaProjects\javapoi-anli\product-test.xlsx 的Excel文件导入到数据库;
Excel的导出
2将数据库product表的数据导出到文件路径为D:\Users\Mixi\IdeaProjects\javapoi-anli\product-test1.xlsx的Excel中;
Excel的导入
1原有数据库product表中数据

2需要导入的excel文件数据
文件路径:D:\Users\Mixi\IdeaProjects\javapoi-anli\product-test.xlsx

3Excel导入执行结果

Excel的导出
1原有数据库product表中数据

2Excel导出执行结果

源码:
1层级关系

web层的Show类:可以理解为Controller层,接收前端的请求实现Excel的导入和导出
/**
 * 模仿前端发送请求到后端
 * 前端传递的应该是一个axios请求到后端,然后将文件的路径传递到后端
 * 后端通过判断是导入还是导出,根据文件地址进行写入数据库或者导出数据库数据到Excel
 * */
public class Show {
    public static void main(String[] args) throws IOException {
        //通过键盘录入Scanner
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你要选择的功能: 1.导入 2.导出");
        int num = sc.nextInt();
        ProductService productService = new ProductServiceImpl();
        if (num == 1) {
            /**
             * 1.导入(导入就是将Excel中的数据存储到数据库)
             * 1.1读取excel表中的数据
             * 前端选择一个路径下的Excel文件进行导入到数据库
             * */
            System.out.println("请输入您要读取的文件位置(不包含空格)");
            String path = sc.next();
            // add
            path = URLDecoder.decode(path, "UTF-8");
            // 将excel文件进行读取(读取成一个个的Product集合)
            List<Product> productList = read(path);
            System.out.println(productList);
            //1.2将数据写入到数据库中(导入)
            productService.save(productList);
            System.out.println("数据已存入数据库中!");
        } else if (num == 2) {
            /**
             * 2.导出(Excel导出==就是将数据库中的数据读取处理啊)
             * 2.1 读取数据库中的数据(从数据库读取的数据是Product的集合)
             * findAll查找到所有的数据
             * */
            List<Product> productList = productService.findAll();
            System.out.println(productList);
            //2.2将数据写入到excel表格中
            System.out.println("请输入要写入的文件位置:");
            String path = sc.next();
            // 将数据库中的所有数据写入到Excel表中并存放在指定位置
            write(productList, path);
            System.out.println("写入成功!");
        } else {
            System.out.println("输入有误,请重新启动");
        }
    }
    /**
     * read方法是用来将Excel文件中的数据导入到数据库
     */
    public static List<Product> read(String path) throws IOException {
        /**
         * 存放多个Product,就是多条数据
         * */
        List<Product> productList = new ArrayList<>();
        //1.获取工作薄 path就是需要导出的Excel文件路径
        XSSFWorkbook xssfWorkbook = new XSSFWorkbook(path);
        //2.获取工作表
        XSSFSheet sheet = xssfWorkbook.getSheetAt(0);
        // 获取到最后一行
        int lastRowNum = sheet.getLastRowNum();
        // 从第一行进行获取数据
        for (int i = 1; i <= lastRowNum; i++) {
            // 工作表获取到每一行
            XSSFRow row = sheet.getRow(i);
            // 空值校验
            if (row != null) {
                List<String> list = new ArrayList<>();
                // 对行进行遍历获取单元格
                for (Cell cell : row) {
                    // 空值校验
                    if (cell != null) {
                        // 为了避免有的单元格不是String类型,所以统一设置成String格式
                        cell.setCellType(Cell.CELL_TYPE_STRING);
                        // 再获取单元格中的数据(从而避免类型转换异常)
                        String value = cell.getStringCellValue();//读取数据
                        /**
                         * 将每一行中单元格中的数据获取到过后存储到String类型的list集合当中
                         * 最后将list集合中的每个数据使用有参构造的方式封装到Product对象中
                         * */
                        if (value != null && !"".equals(value)) {
                            list.add(value);
                        }
                    }
                }
                /**
                 * 最后将list集合中的每个数据使用有参构造的方式封装到Product对象中
                 * 通过下标的方式
                 * */
                // 集合的size()大于0
                if (list.size() > 0) {
                    // 因为Product中的类型不一样,需要转换
                    Product product = new Product(Integer.parseInt(list.get(0)), list.get(1), Double.parseDouble(list.get(2)), Integer.parseInt(list.get(3)));
                    // 添加到Product类型的集合中去
                    productList.add(product);
                }
            }
        }
        // 返回集合
        return productList;
    }
    /**
     * 导出Excel
     * write方法是用来导出Excel
     * 传递的集合是数据库中的所有数据,和导出Excel存放的地址
     */
    public static void write(List<Product> productList, String path) throws IOException {
        //1.创建一个工作薄
        XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
        //2.创建工作表
        XSSFSheet sheet = xssfWorkbook.createSheet("商品");
        //创建单元格样式
        XSSFCellStyle cellStyle = xssfWorkbook.createCellStyle();
        cellStyle.setFillForegroundColor(IndexedColors.PINK.getIndex());
        cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);
        //字体样式
        XSSFFont font = xssfWorkbook.createFont();
        font.setFontName("黑体");
        font.setColor(IndexedColors.BLUE.getIndex());
        cellStyle.setFont(font);
        //3.创建行【第一行】
        XSSFRow row = sheet.createRow(0);
//       row.createCell(0).setCellValue("商品编号");
//       row.createCell(1).setCellValue("商品名称");
//       row.createCell(2).setCellValue("商品价格(单位:元/斤)");
//       row.createCell(3).setCellValue("商品库存(单位:吨)");
        XSSFCell cell = row.createCell(0);
        cell.setCellValue("商品编号");
        // 设计样式
        cell.setCellStyle(cellStyle);
        XSSFCell cell1 = row.createCell(1);
        cell1.setCellValue("商品名称");
        cell1.setCellStyle(cellStyle);
        XSSFCell cell2 = row.createCell(2);
        cell2.setCellValue("商品价格(单位:元/斤)");
        cell2.setCellStyle(cellStyle);
        XSSFCell cell3 = row.createCell(3);
        cell3.setCellValue("商品库存(单位:吨)");
        cell3.setCellStyle(cellStyle);
        for (int i = 0; i < productList.size(); i++) {
            // 从第二行开始创建
            XSSFRow row1 = sheet.createRow(i + 1);
            // 创建单元格进行赋值
            row1.createCell(0).setCellValue(productList.get(i).getPid());
            row1.createCell(1).setCellValue(productList.get(i).getPname());
            row1.createCell(2).setCellValue(productList.get(i).getPrice());
            row1.createCell(3).setCellValue(productList.get(i).getPstock());
        }
        // 创建文件输出流【IO流的方式】
        FileOutputStream fileOutputStream = new FileOutputStream(path);
        // 将文件输出流写到Excel中
        xssfWorkbook.write(fileOutputStream);
        // 刷新
        fileOutputStream.flush();
        // 关流
        fileOutputStream.close();
        xssfWorkbook.close();
    }
}
 
ProductService:Show类中调用的接口
public interface ProductService {
    void save(List<Product> productList);
    List<Product> findAll();
} 
ProductServiceImpl:接口的实现类
public class ProductServiceImpl implements ProductService {
    private ProductDao productDao = new ProductDaoImpl();
    /**
     * 导入
     * 将Excel中的每行数据封装成Product对象再封装到集合当中进行遍历保存到数据库
     */
    @Override
    public void save(List<Product> productList) {
        for (Product product : productList) {
            productDao.save(product);
        }
    }
    /**
     * 导出
     */
    @Override
    public List<Product> findAll() {
        return productDao.findAll();
    }
}
 
ProductDao
public interface ProductDao {
    /**
     * Excel导入到数据库
     */
    void save(Product product);
    /**
     * 数据库导出到Excel
     */
    List<Product> findAll();
} 
ProductDaoImpl:JDBC来实现增删改查,使用xml文件书写也是可以的
public class ProductDaoImpl implements ProductDao {
    JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
    /**
     * 保存,用来Excel的导入
     */
    @Override
    public void save(Product product) {
        // https://www.cnblogs.com/TestAndDevelp/p/12378898.html 参考文章
        String sql = "insert into product values(?,?,?,?)";
        // 将sql中的占位符进行一个替换
        jdbcTemplate.update(sql, product.getPid(), product.getPname(), product.getPrice(), product.getPstock());
    }
    /**
     * 查找数据,用来Excel的导出
     */
    @Override
    public List<Product> findAll() {
        String sql = "select * from product";
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<Product>(Product.class));
    }
}
 
domain层的Product:实体类
/**
 * Excel表对应的实体类
 * */
public class Product {
    private Integer pid;
    private String pname;
    private double price;
    private int pstock;
    @Override
    public String toString() {
        return "Product{" +
                "pid=" + pid +
                ", pname='" + pname + '\'' +
                ", price=" + price +
                ", pstock=" + pstock +
                '}';
    }
    public Product(Integer pid, String pname, double price, int pstock) {
        this.pid = pid;
        this.pname = pname;
        this.price = price;
        this.pstock = pstock;
    }
    public Product() {
    }
    public Integer getPid() {
        return pid;
    }
    public void setPid(Integer pid) {
        this.pid = pid;
    }
    public String getPname() {
        return pname;
    }
    public void setPname(String pname) {
        this.pname = pname;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getPstock() {
        return pstock;
    }
    public void setPstock(int pstock) {
        this.pstock = pstock;
    }
} 
测试:执行main方法,输入1或者2,输入导入文件的路径或Excel文件需要导出的路径
1测试导入功能

2测试导出功能

gitee源码链接:javapoi-excel: POI实现Excel的导入和导出









![[附源码]计算机毕业设计springboot家庭医生签约服务管理系统](https://img-blog.csdnimg.cn/7d39b4d997f14cafb34b19e7ab549a7b.png)









