POI实现Excel导入和导出(源码测试)
创始人
2024-03-05 05:02:28
0

        因为实际开发中很多需求都需要实现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 {//通过键盘录入ScannerScanner 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();// addpath = URLDecoder.decode(path, "UTF-8");// 将excel文件进行读取(读取成一个个的Product集合)List 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 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 read(String path) throws IOException {/*** 存放多个Product,就是多条数据* */List 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 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()大于0if (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 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 productList);List findAll();}

 ProductServiceImpl:接口的实现类

public class ProductServiceImpl implements ProductService {private ProductDao productDao = new ProductDaoImpl();/*** 导入* 将Excel中的每行数据封装成Product对象再封装到集合当中进行遍历保存到数据库*/@Overridepublic void save(List productList) {for (Product product : productList) {productDao.save(product);}}/*** 导出*/@Overridepublic List findAll() {return productDao.findAll();}
}

ProductDao

public interface ProductDao {/*** Excel导入到数据库*/void save(Product product);/*** 数据库导出到Excel*/List findAll();}

ProductDaoImpl:JDBC来实现增删改查,使用xml文件书写也是可以的

public class ProductDaoImpl implements ProductDao {JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());/*** 保存,用来Excel的导入*/@Overridepublic 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的导出*/@Overridepublic List findAll() {String sql = "select * from product";return jdbcTemplate.query(sql, new BeanPropertyRowMapper(Product.class));}}

domain层的Product:实体类

/*** Excel表对应的实体类* */
public class Product {private Integer pid;private String pname;private double price;private int pstock;@Overridepublic 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的导入和导出

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...