《苍穹外卖》知识梳理P11-Apache POI导出报表

一.Apache POI

可以通过Apache POI处理excel文件,核心操作是读和写

应用场景

  • 银行网银交易明细
  • 各种业务系统导出Excel报表
  • 批量导入业务数据

使用步骤

1.导入maven坐标

xml 复制代码
		<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>

2.测试代码(写操作)

java 复制代码
	public class PoiTest {
	
	    /**
	     * 写操作
	     * 通过POI创建excel文件并写入文件内容
	     */
	    public static void write() throws IOException {
	        //在内存中创建一个excel文件XSSFWorkbook表示excel文件
	        XSSFWorkbook excel = new XSSFWorkbook();
	        //在excel文件中创建一个sheet页
	        XSSFSheet sheet = excel.createSheet("info");
	        //在sheet页中创建行对象,i表示第i+1行
	        XSSFRow row = sheet.createRow(1);
	        //在行上创建单元格,并写入内容
	        row.createCell(1).setCellValue("姓名");
	        row.createCell(2).setCellValue("城市");
	
	        row = sheet.createRow(2);
	        row.createCell(1).setCellValue("张三");
	        row.createCell(2).setCellValue("北京");
	
	        row = sheet.createRow(3);
	        row.createCell(1).setCellValue("李四");
	        row.createCell(2).setCellValue("东京");
	
	        //通过输出流将内存中的内容输出到文件中
	        FileOutputStream fileOutputStream=new FileOutputStream(new File("D:\\info.xlsx"));
	        excel.write(fileOutputStream);
	        fileOutputStream.close();
	        excel.close();
	    }
	
	    public static void main(String[] args) throws Exception {
	        write();
	    }
	}

3.运行结果(写操作)

4.测试代码(读操作)

java 复制代码
	public class PoiTest {

	    /**
	     * 通过POI读取excel文件中内容
	     */
	    public static void read() throws IOException {
	        //通过输入流读取一个磁盘中的文件内容;
	        FileInputStream inputStream = new FileInputStream(new File("D:\\info.xlsx"));
	        //在内存中创建一个excel文件XSSFWorkbook表示excel文件,并传入输入流
	        XSSFWorkbook excel=new XSSFWorkbook(inputStream);
	        //按照sheet页的名称读取
	        XSSFSheet sheet=excel.getSheetAt(0);
	        int lastRowNum = sheet.getLastRowNum();//获取有文字的最后一行的行号(从0开始);
	        for (int i = 1; i < lastRowNum; i++) {
	            //获取某一行
	            XSSFRow row=sheet.getRow(i);
	            if (row==null) continue;
	            //获取单元格对象
	            String cellValue=row.getCell(1).getStringCellValue();
	            String cellValue1=row.getCell(2).getStringCellValue();
	            System.out.println(cellValue+" "+cellValue1);
	        }
	        //关闭输入流
	        inputStream.close();
	        //关闭资源
	        excel.close();
	    }
	
	    public static void main(String[] args) throws Exception {
	//        write();
	        read();
	    }
	}

5.运行结果(读操作)

二.导出Excel报表

由于实际业务中可能会有复杂的报表格式,如果直接使用POI进行读取操作十分繁琐,通常是先在windows上对报表格式进行设计,得到一个模版文件,直接读入模版文件进行操作即可

  • 设计模版文件
  • 查询xx天的数据
  • 将查询到的数据写入模版文件
  • 通过输出流将excel文件下载到客户端浏览器

实现步骤

  • 项目中导入模版文件,在src/main/resources/下新建template目录用来存放模版文件,将模版.xlsx导入
  • 编写代码,对指定位置进行填充,写入excel文件中的格式基本是固定的,我认为关键在于传递的参HttpServletResponse response,response.getOutputStream(): 通过调用response对象的getOutputStream()方法,获取到一个Servlet输出流。Servlet输出流是用于向客户端发送数据的输出流,通过这个输出流可以将数据发送到客户端。excel.write(outputStream): 调用excel对象的write()方法,将Excel文件内容写入到之前获取的Servlet输出流中。这会将Excel文件的内容写入到HTTP响应的输出流中,实际上是将Excel文件的字节流发送到客户端浏览器。然后客户端浏览器获得响应后自动开始下载文件.
java 复制代码
	//通过输出流将excel下载到客户浏览器
    ServletOutputStream outputStream = response.getOutputStream();
    excel.write(outputStream);

    //关闭资源
    outputStream.close();
    excel.close();

业务层完整代码

java 复制代码
	/**
     * 导出运行数据报表
     *
     * @param response
     */
    @Override
    public void exportBusinessData(HttpServletResponse response) {
        //查数据库获取营业数据
        LocalDate dateBegin = LocalDate.now().minusDays(30);
        LocalDate dateEnd = LocalDate.now().minusDays(1);
        //将日期转换为详细时间
        LocalDateTime dateStartPoint = LocalDateTime.of(dateBegin, LocalTime.MIN);
        LocalDateTime dateEndPoint = LocalDateTime.of(dateEnd, LocalTime.MAX);
        BusinessDataVO businessData = workspaceService.getBusinessData(dateStartPoint, dateEndPoint);
        ClassLoader loader = getClass().getClassLoader();
        InputStream stream = loader.getResourceAsStream("template/运营数据报表模板.xlsx");
        log.info("读入的输入流stream{}",stream);
        //从类路径下边读取资源
        InputStream inputStream = ReportServiceImpl.class.getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
//        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");

        try {
            //基于模版文件创建一个新的excel文件
            XSSFWorkbook excel=new XSSFWorkbook(inputStream);
            XSSFSheet sheet1 = excel.getSheet("Sheet1");
            //填充数据,填充时间
            sheet1.getRow(1).getCell(1).setCellValue("时间"+dateBegin+"至"+dateEnd);

            //获得第四行
            XSSFRow row=sheet1.getRow(3);
            row.getCell(2).setCellValue(businessData.getTurnover());
            row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessData.getNewUsers());

            //获得第五行
            row=sheet1.getRow(4);
            row.getCell(2).setCellValue(businessData.getValidOrderCount());
            row.getCell(4).setCellValue(businessData.getUnitPrice());

            //填充明细数据
            for (int i=0;i<30;i++){
                LocalDate date=dateBegin.plusDays(1);
                //查询某一天的数据
                workspaceService.getBusinessData(LocalDateTime.of(dateBegin,LocalTime.MIN),
                        LocalDateTime.of(dateBegin,LocalTime.MAX));
                //获取某一行
                row = sheet1.getRow(7 + i);
                row.getCell(1).setCellValue(date.toString());
                row.getCell(2).setCellValue(businessData.getTurnover());
                row.getCell(3).setCellValue(businessData.getValidOrderCount());
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessData.getUnitPrice());
                row.getCell(5).setCellValue(businessData.getNewUsers());

            }

            //通过输出流将excel下载到客户浏览器
            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);

            //关闭资源
            outputStream.close();
            excel.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
        //将查询到的数据写入到Excel文件中

    }

实现效果

备注:并不是下载了5个(是我之前测试用的提前下载了4个)

相关推荐
禁默25 分钟前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
Cachel wood32 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Code哈哈笑34 分钟前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
gb421528737 分钟前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端
程序猿进阶38 分钟前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
zfoo-framework1 小时前
【jenkins插件】
java
风_流沙1 小时前
java 对ElasticSearch数据库操作封装工具类(对你是否适用嘞)
java·数据库·elasticsearch
ProtonBase1 小时前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构
乐之者v1 小时前
leetCode43.字符串相乘
java·数据结构·算法