报表技术1-POI导入导出

Excel说明

在企业级应用开发中,Excel报表是一种最常见的报表需求。Excel报表开发一般分为两种形式:

  • 为了方便操作,基于Excel的报表批量上传数据,也就是把Excel中的数据导入到系统中。
  • 通过java代码生成Excel报表。也就是把系统中的数据导出到Excel中,方便查阅。

Excel的两种版本

  • Excel2003 是一个特有的二进制格式,其核心结构是复合文档类型的结构,存储数据量较小;
  • Excel2007 的核心结构是 XML 类型的结构,采用的是基于 XML 的压缩方式,使其占用的空间更小,操作效率更高。

常见的Excel操作工具

JXL(很少使用)

JXL只能对Excel进行操作,属于比较老的框架,它只支持到Excel 95-2000的版本。现在已经停止更新和维护,所以本课程中只时简单地演示一下jxl的代码,不会把它作为重点。
主要语法:
1、 创建可写入的Excel工作薄

WritableWorkbook workbook= Workbook.createWorkbook(输出流);

2、创建工作表

WritableSheet sheet= workbook.createSheet(工作表的名称, 工作表的索引值);

3、创建单元格

添加文本类单元格

Label labelC = new Label(列索引值, 行索引值, “单元格中的内容”);
sheet.addCell(labelC);

4、写入到文件

workbook.write();// 写入数据

5、释放资源:

workbook.close();// 关闭文件

导出一些个简单的excel(很少使用)
public void downLoadXlsByJxl(HttpServletResponse response){
        try {
           //创建一个工作薄
            ServletOutputStream outputStream = response.getOutputStream();
            WritableWorkbook workbook = Workbook.createWorkbook(outputStream);
           //创建一个工作表
            WritableSheet sheet = workbook.createSheet("一个JXL入门", 0);
           //设置列宽
            sheet.setColumnView(0,5);
            sheet.setColumnView(1,8);
            sheet.setColumnView(2,15);
            sheet.setColumnView(3,15);
            sheet.setColumnView(4,30);
            //处理标题
            String[] titles = new String[]{"编号","姓名","手机号","入职日期","现住址"};
            Label label = null;
            for (int i = 0; i < titles.length; i++) {
                label = new Label(i,0,titles[i]);
                sheet.addCell(label);
            }
            //处理导出的内容
            List<User> userList = this.findAll();
            int rowIndex = 1;
            for (User user : userList) {
                label = new Label(0,rowIndex,user.getId().toString());
                sheet.addCell(label);
                label = new Label(1,rowIndex,user.getUserName());
                sheet.addCell(label);
                label = new Label(2,rowIndex,user.getPhone());
                sheet.addCell(label);
                label = new Label(3,rowIndex,simpleDateFormat.format(user.getHireDate()));
                sheet.addCell(label);
                label = new Label(4,rowIndex,user.getAddress());
                sheet.addCell(label);
                rowIndex++;
            }
            
            //导出的文件名称
            String filename="一个JXL入门.xls";
            //设置文件的打开方式和mime类型
             response.setHeader( "Content-Disposition", "attachment;filename="  + new String(filename.getBytes(),"ISO8859-1"));
            response.setContentType("application/vnd.ms-excel"); 
           //导出
            workbook.write();
            //关闭资源
            workbook.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

结果如图:
在这里插入图片描述

POI(重点)

  • POI是apache的项目,可对微软的Word,Excel,PPT进行操作,包括office2003和2007,Excle2003和2007。POI现在一直有更新。所以现在主流使用POI。
  • Apache POI是Apache软件基金会的开源项目,由Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java语言操作Microsoft Office的功能。

API对象介绍:

工作簿:WorkBookHSSFWordBook :2003版本,XSSFWorkBook :2007级以上
工作表 : SheetHSSFSheet :2003版本,XSSFSheet :2007级以上
行 :RowHSSFRow :2003版本,XSSFRow :2007级以上
单元格: CellHSSFCell :2003版本,XSSFCell :2007级以上

POI操作Excel高低版本区别
只是类名不一样,方法都一样

对应excel名称低版本中的类名高版本中的类名
工作簿HSSFWorkbookXSSFWorkbook
工作表HSSFSheetXSSFSheet
HSSFRowXSSFRow
单元格HSSFCellXSSFCell
单元格样式HSSFCellStyleXSSFCellStyle

1.添加依赖

处理低版本excel
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.0.1</version>
</dependency>

处理高版本excel
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.0.1</version>
</dependency>

处理百万数据,导入导出
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.0.1</version>
</dependency>

2.代码测试

操作低版本

public class POIDemo01 {
    public static void main(String[] args) throws Exception {
        //1.创建一个全新工作簿
        Workbook workbook = new HSSFWorkbook();
        //2.在工作簿中创建新的工作表
        Sheet sheet = workbook.createSheet("POI操作");
        //3.在工作表中创建行-行的脚标
        Row row = sheet.createRow(0);
        //4.在行中创建单元格-单元格脚标
        Cell cell = row.createCell(0);
        //5.在单元格写入内容
        cell.setCellValue("第一行第一列的单元格数据");
        workbook.write(new FileOutputStream(new File("D:/test.xls")));
        workbook.close();
    }
}

操作高版本

public class POIDemo02 {
    public static void main(String[] args) throws Exception{
        Workbook workbook = new XSSFWorkbook(); //创建了一个全新(里面什么都没有)的工作薄
        Sheet sheet = workbook.createSheet("demo测试");  //创建了一个全新(里面什么都没有)的工作表
        Row row = sheet.createRow(0);  //创建了第一行(空的)
        Cell cell = row.createCell(0);//创建的是第一行的第一个单元格
        cell.setCellValue("这是我第一次玩POI");
        //把工作薄输出到本地磁盘
        workbook.write(new FileOutputStream("d://test.xlsx"));
    }
}

结果:
在这里插入图片描述

数据导入

数据的导入就是读取excel中的内容,转成对象插入到数据库中

实现步骤:
1、根据上传的文件创建Workbook
2、获取到第一个sheet工作表
3、从第二行开始读取数据
4、读取每一个单元格,把内容放入到用户对象的相关的属性中

   public void uploadExcel(MultipartFile file) throws Exception {

        SimpleDateFormat simpleDateFormat = new  SimpleDateFormat("yyyy-MM-dd");

        //有内容的workbook
        Workbook workbook = new XSSFWorkbook(file.getInputStream());
        
        //获取到第一个工作表
        Sheet sheet = workbook.getSheetAt(0);
        
        //读取工作表中的内容
        //获取当前sheet的最后一行的索引值
        int lastRowIndex = sheet.getLastRowNum();
        
        Row row = null;
        
        //遍历读取工作表中的内容,数据类型
        for (int i = 1; i <= lastRowIndex; i++) {
            row = sheet.getRow(i);
            String username = row.getCell(0).getStringCellValue();
            String phone = null;
            try {
                phone = row.getCell(1).getStringCellValue()+"";
            } catch (Exception e) {
                e.printStackTrace();
            }
            String province = row.getCell(2).getStringCellValue();
            String city = row.getCell(3).getStringCellValue();
            
            //double类型转Integer
            Integer salary = ((Double) row.getCell(4).getNumericCellValue()).intValue();
            //日期格式转换
            Date hireDate = simpleDateFormat.parse(row.getCell(5).getStringCellValue());
            Date birthDay = simpleDateFormat.parse(row.getCell(6).getStringCellValue());
            String address = row.getCell(7).getStringCellValue();
            
            //封装用户信息
            User user = new User();
            user.setUserName(username);
            user.setBirthday(birthDay);
            user.setAddress(address);
            user.setCity(city);
            user.setHireDate(hireDate);
            user.setProvince(province);
            user.setSalary(salary);
            user.setPhone(phone);
            //执行插入方法
            //System.out.println(user.toString());
            userMapper.insert(user);
        }

    }

数据导出

1、创建一个全新的工作薄
2、在新的工作薄中创建一个新的工作表
3、在工作表创建第一行作为标题行,标题固定
4、从第二行循环遍历创建,有多少条用户数据就应该创建多少行
5、把每一个user对象的属性放入到相应的单元格中

public void downLoadXlsx(HttpServletResponse response) throws Exception {

    private SimpleDateFormat simpleDateFormat = new  SimpleDateFormat("yyyy-MM-dd");
    
         //1.创建一个全新的工作簿
        Workbook workbook = new XSSFWorkbook();
        
        //2.创建全新的工作表
        Sheet sheet = workbook.createSheet("用户数据");
        
        //调整列宽var1索引值, var2 1代表一个标准字母的1/256
        sheet.setColumnWidth(0,5*256);
        sheet.setColumnWidth(1,8*256);
        sheet.setColumnWidth(2,10*256);
        sheet.setColumnWidth(3,15*256);
        sheet.setColumnWidth(4,30*256);
        
        //3.处理固定的标题---编号,姓名,手机号,入职日期,现住址
        String[] title = new String[]{"编号","姓名","手机号","入职日期","现住址"};
        
        //标题行
        Row titleRow = sheet.createRow(0);
        Cell cell = null;
        for (int i = 0; i < 5; i++) {
            cell = titleRow.createCell(i);
            cell.setCellValue(title[i]);
        }
        
        //4.从第二行循环遍历,向单元格中放入数据
        List<User> list = userMapper.selectAll();
        int rowIndex = 1;
        Row row = null;
        
        for (User user : list) {
            row = sheet.createRow(rowIndex);
            cell = row.createCell(0);
            cell.setCellValue(user.getId());
            cell = row.createCell(1);
            cell.setCellValue(user.getUserName());
            cell = row.createCell(2);
            cell.setCellValue(user.getPhone());
            cell = row.createCell(3);
            cell.setCellValue(simpleDateFormat.format(user.getHireDate()));
            cell = row.createCell(4);
            cell.setCellValue(user.getBirthday());
            rowIndex++;
        }
        
        //一个流两个头
        String fileName = "员工数据.xlsx";
        response.setHeader("content-disposition","attachment;filename="+new String(fileName.getBytes(),"ISO8859-1"));
        response.setContentType("application/vnd.ms-excel");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        //执行
        workbook.write(response.getOutputStream());
    }

结果:
在这里插入图片描述

导出带样式的数据(不建议)

      /**
     * POI导出用户数据---简单样式
     * @param response
     * @throws Exception
     */
    public void downLoadXlsxByPoiWithCellStyle(HttpServletResponse response) throws Exception {
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet();

        /**
         * 大标题行
         */
        Row bigTitleRow = sheet.createRow(0);

        //1.边框线(全边框),行高(42),合并单元格(第一行第一个到第五个单元格),对齐方式(水平垂直居中),字体:黑体18号
        CellStyle bigTitleRowCellStyle = workbook.createCellStyle();

        //上下左右边框
        bigTitleRowCellStyle.setBorderTop(BorderStyle.THIN);//BorderStyle.THIN细线
        bigTitleRowCellStyle.setBorderBottom(BorderStyle.THIN);
        bigTitleRowCellStyle.setBorderLeft(BorderStyle.THIN);
        bigTitleRowCellStyle.setBorderRight(BorderStyle.THIN);
        //对齐方式,水平居中对齐,垂直居中对齐
        bigTitleRowCellStyle.setAlignment(HorizontalAlignment.CENTER);
        bigTitleRowCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        //设置行高
        bigTitleRow.setHeightInPoints(42);

        //设置列宽
        sheet.setColumnWidth(0,5*256);
        sheet.setColumnWidth(1,10*256);
        sheet.setColumnWidth(2,10*256);
        sheet.setColumnWidth(3,10*256);
        sheet.setColumnWidth(4,30*256);

        //字体
        //1.创建字体
        Font font = workbook.createFont();
        //2.设置字体样式
        font.setFontName("黑体");
        font.setFontHeightInPoints((short) 18);
        //3.字体放入样式中
        bigTitleRowCellStyle.setFont(font);

        //--5个单元格合并
        for (int i = 0; i < 5; i++) {
            Cell cell = bigTitleRow.createCell(i);
            cell.setCellStyle(bigTitleRowCellStyle);
        }
        //起始行,结束行,开始列,结束列
        sheet.addMergedRegion(new CellRangeAddress(0,0,0,4));

        //向单元格中添加句子
        bigTitleRow.getCell(0).setCellValue("用户信息数据");
        //大标题行结束

        /**
         * 小标题行
         */
        Row littleTitleRow = sheet.createRow(1);

        //1.边框线(全边框),行高(42),合并单元格(第一行第一个到第五个单元格),对齐方式(水平垂直居中),字体:黑体18号
        CellStyle littleTitleRowCellStyle = workbook.createCellStyle();

        //克隆大标题的样式
        //上下左右边框
        //对齐方式,水平居中对齐,垂直居中对齐
        littleTitleRowCellStyle.cloneStyleFrom(bigTitleRowCellStyle);

        //设置列宽
        littleTitleRow.setHeightInPoints(32);
        //字体
        //1.创建字体
        Font littleFont = workbook.createFont();
        //2.设置字体样式
        littleFont.setFontName("宋体");
        littleFont.setFontHeightInPoints((short) 12);
        littleFont.setBold(true);
        //3.字体放入样式中
        littleTitleRowCellStyle.setFont(littleFont);

        //添加小标题内容
        String[] titles = new String[]{"编号","姓名","手机号","入职日期","现住址"};
        for (int i = 0; i < 5; i++) {
            Cell cell = littleTitleRow.createCell(i);
            cell.setCellValue(titles[i]);
            cell.setCellStyle(littleTitleRowCellStyle);
        }
        //小标题行结束
        
        /**
         * 内容样式
         */
        CellStyle contentRowCellStyle = workbook.createCellStyle();
        contentRowCellStyle.cloneStyleFrom(bigTitleRowCellStyle);
        contentRowCellStyle.setAlignment(HorizontalAlignment.LEFT);
        Font contentFont = workbook.createFont();
        contentFont.setFontName("宋体");
        contentFont.setFontHeightInPoints((short) 11);
        contentFont.setBold(false);
        contentRowCellStyle.setFont(contentFont);

        Row contentRow = null;
        Cell cell = null;
        int contentRowIndex = 2;
        
        //添加用户数据
        List<User> users = userMapper.selectAll();
        for (User user : users) {
            contentRow = sheet.createRow(contentRowIndex);

            cell = contentRow.createCell(0);
            cell.setCellValue(user.getId());

            cell = contentRow.createCell(1);
            cell.setCellValue(user.getUserName());

            cell = contentRow.createCell(2);
            cell.setCellValue(user.getPhone());

            cell = contentRow.createCell(3);
            cell.setCellValue(simpleDateFormat.format(user.getHireDate()));

            cell = contentRow.createCell(4);
            cell.setCellValue(user.getAddress());

            cell.setCellStyle(contentRowCellStyle);
            contentRowIndex++;
        }
        /**
         * 一个流两个头
         */
        String fileName = "员工样式数据.xlsx";
        response.setHeader("content-disposition","attachment;filename="+new String(fileName.getBytes(),"ISO8859-1"));
        response.setContentType("application/vnd.ms-excel");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        workbook.write(response.getOutputStream());
    }

结果:
在这里插入图片描述

根据模板导出数据

    public void downLoadXlsxByPoiWithTemplate(HttpServletResponse response) throws Exception {
       
        //1.获取到模板
        //获取项目的根目录,创建目录
        File rootFile = new File(ResourceUtils.getURL("classpath:").getPath());
        File templateFile = new File(rootFile, "/excel_template/userList.xlsx");
        //创建有模板的工作簿
        Workbook workbook = new XSSFWorkbook(templateFile);
        Sheet sheet = workbook.getSheetAt(0);
       
        //2.查询所有的用户数据
        List<User> list = userMapper.selectAll();
       
        //3.放入到模板中
        int rowIndex = 2;
        Row row = null;
        Cell cell = null;
   
        //获取准备好的内容单元格样式,第二个sheet的第一个单元格的样式
        CellStyle cellStyle = workbook.getSheetAt(1).getRow(0).getCell(0).getCellStyle();
		//遍历结果
        for (User user : list) {
            row = sheet.createRow(rowIndex);
            row.setHeightInPoints(15);
            cell = row.createCell(0);
            cell.setCellValue(user.getId());
            cell = row.createCell(1);
            cell.setCellValue(user.getUserName());
            cell.setCellStyle(cellStyle);
            cell = row.createCell(2);
            cell.setCellValue(user.getPhone());
            cell.setCellStyle(cellStyle);
            cell = row.createCell(3);
            cell.setCellValue(simpleDateFormat.format(user.getHireDate()));
            cell.setCellStyle(cellStyle);
            cell = row.createCell(4);
            cell.setCellValue(user.getAddress());
            cell.setCellStyle(cellStyle);
            rowIndex++;
        }
        
        //删除第二个sheet
        workbook.removeSheetAt(1);
        
        //4.导出文件
        //一个流两个头
        String fileName = "员工模板数据.xlsx";
        response.setHeader("content-disposition","attachment;filename="+new String(fileName.getBytes(),"ISO8859-1"));
        response.setContentType("application/vnd.ms-excel");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        //执行
        workbook.write(response.getOutputStream());
    }

模板样式:sheet1
在这里插入图片描述
sheet2
在这里插入图片描述

代码:https://gitee.com/suisui9857/user_management

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值