java - - 导入、导出表格到 Excel文档

java - - 导入、导出表格到 Excel文档

🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬

1、poi导出 – 较复杂表格

1、🍬🍬先导入依赖

		 <!-- 导入导出依赖 -->
 		<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>

2、🍬🍬在路径 WEB-INF 下新建包 fileDown 然后把需要导出Excel的模板放入

(用javaPOI导出Excel时,需要考虑Excel版本和数据量的问题 可以去百度了解)

###在这里插入图片描述

Java POI 导出 Excel 有三种形式:

HSSFWorkbook : 是操作Excel2003以前(包括2003)的版本,扩展名是 .xls;

XSSFWorkbook : 是操作Excel2007后的版本,扩展名是 .xlsx;

SXSSFWorkbook : 是操作Excel2007后的版本,扩展名是 .xlxs;

3、🍬🍬Controller层

 @ResponseBody
    @RequestMapping("/getTongjiTable")
    public String getTongjiTable(String page, String rows, String Date, String type, HttpServletRequest request, HttpServletResponse response) throws Exception{
        try {
            String filePath1 = request.getServletContext().getRealPath("") + "WEB-INF" + File.separator+"fileDown" +
                    File.separator+"tongJiTable.xls"; //模板的路径
            String filePathNew = request.getServletContext().getRealPath("") + "WEB-INF" + File.separator+"fileDown" +
                    File.separator+"tongJiTable1.xls"; //模板的路径

            //生成文件的过程
            GridData tongjiTable = iaRealtimeSensorService.getTable(page, rows, Date, type);//GridData Object类
//            List<SData> sDatas = (List<SData>) tongjiTable.getRows();
            List<Map<String, Object>> sDatas = (List<Map<String, Object>>) tongjiTable.getRows();

            String message = Date;
            iaRealtimeSensorService.getTongjiTable(sDatas, filePath1, filePathNew, message);

//==============================================下载文档===============================================================================          
            
            //下载文件的过程
            File fileurl = new File(filePathNew);
            //浏览器下载后的文件名称showValue,从url中截取到源文件名称以及文件类型,如board.docx;
            String string = new SimpleDateFormat("yyyy-MM-dd").format(new Date()).toString();
            String showValue = string+"tongJiTable.xls";
            if(fileurl.exists()){
                InputStream inStream = null;
                try{
                    //将文件读入文件流
                    inStream = new FileInputStream(fileurl);
                    //获得浏览器代理信息
                    //User Agent使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等
                    final String userAgent = request.getHeader("USER-AGENT");
                    //判断浏览器代理并分别设置响应给浏览器的编码格式
                    String finalFileName = showValue;
                    //设置Http响应头
                    response.reset();//重置 响应头
                    //告知浏览器下载文件,而不是直接打开,浏览器默认为打开
                    response.setContentType("application/x-download");
                    //下载文件的名称
                    response.addHeader("Content-Disposition", "attachment;filename=\"" + finalFileName + "\"");
                    //循环取出流中的数据
                    byte[] b = new byte[1024];
                    int len;
                    while ((len = inStream.read(b)) > 0){
                        response.getOutputStream().write(b,0, len);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    inStream.close();
                    response.getOutputStream().close();
                }
            }
            return AjaxResult.success("下载成功", "")+"";
        } catch (Exception e) {
            logger.error("下载失败",e);
            return AjaxResult.error("下载失败")+"";
        }
    }

4、🍬🍬service 层 以及它的实现类

  
//注明 == 涉及到业务层的查询功能 dao层就不展示了 根据自己的查询需求去编写
//先查到要展示的数据
GridData getTable(String page, String rows, String Date, String type)throws Exception;


  @Override
    public GridData getTable(String page, String rows, String DateStr, String type) throws Exception {
        int skip = 0;
        int row = 10;
        //分页
        if (!StringUtils.isEmpty(page) && !StringUtils.isEmpty(rows)){
            int size = Integer.parseInt(rows);
            int number = Integer.parseInt(page);
            if(size != 0){
                row = size;
            }
            if(number < 1){
                number = 1;
            }
            skip = (number - 1) * row;
        }
        GridData dataList = new GridData();
        List<Map<String, Object>> dateRows = new ArrayList<>();
        int total = 0;
        Date dateTime = null;
        Date date = new Date();//获取当前时间
        if(!StringUtils.isEmpty(DateStr)){
            //type为传参类型 0 年 ,1 月 , 默认为空查当前月份
            if("0".equals(type)){//0 查年统计表
                //时间格式转换
                SimpleDateFormat ft0 = new SimpleDateFormat("yyyy");
                dateTime = ft0.parse(DateStr);
                dateRows = isDataSDao.getTongjiYear(skip, row, dateTime);
                total = isDataSDao.getTongjiYearCount(dateTime);
                if(dateRows != null && dateRows.size()>0){
                    for(Map<String, Object> map : dateRows){
                        String time = map.get("time") + "月";
                        map.remove("time");
                        map.put("time", time);
                    }
                }
            }else if("1".equals(type)){//1 查月统计
                //时间格式转换
                SimpleDateFormat ft1 = new SimpleDateFormat("yyyy-MM");
                dateTime = ft1.parse(DateStr);
                dateRows = isDataSDao.getTongjiMonth(skip,row,dateTime);
                total = isDataSDao.getTongjiMonthCount(dateTime);
                if(dateRows != null && dateRows.size()>0){
                    for(Map<String, Object> map : dateRows){
                        String time = map.get("time") + "日";
                        map.remove("time");
                        map.put("time", time);
                    }
                }
            }
        }else {
            //获取当前月份
            dateTime = date;
            dateRows = isDataSDao.getTongjiMonth(skip,row,dateTime);
            total = isDataSDao.getTongjiMonthCount(dateTime);
            if(dateRows != null && dateRows.size()>0){
                for(Map<String, Object> map : dateRows){
                    String time = map.get("time") + "日";
                    map.remove("time");
                    map.put("time", time);
                }
            }
        }
        dataList.setTotal(total);
        dataList.setRows(dateRows);
        return dataList;
    }

//========================================================写入数据=======================================================================


//写入数据
void getTongjiTable(List<Map<String, Object>> sDatas, String urlOld, String urlNew, String message)throws Exception;


  @Override
    public void getTongjiTable(List<Map<String, Object>> sDatas, String urlOld, String urlNew, String message) throws Exception {
        //1、删除文件
        String fileName = urlNew;
        File file = new File(fileName);
        if(file.exists()){
            file.delete();
        }

        //2、先拷贝文件
        copyFileUsingJava7Files(new File(urlOld), new File(urlNew));

        FileInputStream fs;
        try {
            fs = new FileInputStream(urlNew);
            POIFSFileSystem ps = new POIFSFileSystem(fs);//使用POI提供的方法得到excel的信息
            //第一步:创建一个webbook, 对应一个Excel
            HSSFWorkbook wb = new HSSFWorkbook(ps);
            //第二步:在webbook添加一个sheet, 与之对应的是Excel中的Excel
            HSSFSheet sheet = wb.getSheetAt(0);//获取到工作表 一个Excel可能存在多个工作表
            //第三步:在sheet中添加表头第0行
            HSSFRow row = sheet.getRow(0);
            HSSFCell cell=row.createCell((short)0);

            HSSFCellStyle style = wb.createCellStyle();
            Font font = wb.createFont();
            font.setFontHeightInPoints((short)30);
            font.setFontName("宋体");   //什么字体
            font.setItalic(false);                 //是不倾斜
            font.setStrikeout(false);         //是不是划掉
            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
            style.setFont(font);
            font.setFontName("库房温湿度统计表"+message);
            cell.setCellValue("库房温湿度统计表"+message);
            style.setUserStyleName("库房温湿度统计表"+message);
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            cell.setCellStyle(style);
            row.createCell(0).setCellValue("库房温湿度统计表"+"("+message+")");

            //行
            int hang = 0;
            if ("".equals(row) || row == null) {
                hang = 0;
            } else {
                hang = sheet.getLastRowNum();
                hang = hang + 1;
            }

            FileOutputStream out = new FileOutputStream(urlNew);//往 url中写入数据  out 输出流

            //处理数据

            if(sDatas != null && sDatas.size()>0){
                int i =1;
                for(Map<String, Object> map : sDatas){
                    row = sheet.createRow((short)(hang++));//在现有行后面追加数据
                    row.createCell(0).setCellValue(i++);//序号
                    if(map.get("time").toString() != null){
                        row.createCell(1).setCellValue(map.get("time").toString());//时间
                    }else {
                        row.createCell(1).setCellValue("");
                    }
                    if(map.get("zuidiwendu").toString() != null){
                        row.createCell(2).setCellValue(map.get("zuidiwendu").toString());//最低温度
                    }else {
                        row.createCell(2).setCellValue("");
                    }
                    if(map.get("zuigaowendu").toString() != null){
                        row.createCell(3).setCellValue(map.get("zuigaowendu").toString());//最高温度
                    }else {
                        row.createCell(3).setCellValue("");
                    }
                    if(map.get("Avgwendu").toString() != null){
                        row.createCell(4).setCellValue(map.get("Avgwendu").toString());//平均温度
                    }else {
                        row.createCell(4).setCellValue("");
                    }
                    if(map.get("zuidishidu").toString() != null){
                        row.createCell(5).setCellValue(map.get("zuidishidu").toString());//最低湿度
                    }else {
                        row.createCell(5).setCellValue("");
                    }
                    if(map.get("zuigaoshidu").toString() != null){
                        row.createCell(6).setCellValue(map.get("zuigaoshidu").toString());//最高湿度
                    }else {
                        row.createCell(6).setCellValue("");
                    }
                    if(map.get("Avgshidu").toString() != null){
                        row.createCell(7).setCellValue(map.get("Avgshidu").toString());//平均湿度
                    }else {
                        row.createCell(7).setCellValue("");
                    }
           		}
            }
            out.flush();
            wb.write(out);
            out.close();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }
    }



🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬🍬

2、按数据单表直接写入、导出 – 简单表格导出

1、写、

1、创建实体类:
@Data
public class ExcelStudentDTO {

    // @ExcelProperty 该注解 可以写入到Excel表格 作为目录
    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty("生日")
    private Date birthday;

    @ExcelProperty("薪资")
    private Double salary;

}
2、写入数据

格式占内存大小存放量 的区别:

  • 相同的数据xlsx占用内存小于xls

  • xls 版本的Excel最多一次可写0 …65535行

  • xlsx 版本的Excel最多一次可写0…1048575行

前提:

需要新建该文件夹 才能将excel文档写入 — E:/实战/实战-金融宝/excel2023/

public class ExcelWriteTest {

    
    // 写法1 JDK8+
    @Test
    public void simpleWriteTestXlsx(){
        //xlsx文档 最多能写一百万多(1048575)条数据 假设要写入的数据够大  须得分开写
        String fileName = "E:/实战/实战-金融宝/excel2023/simpleWrite.xlsx";
        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        // 如果这里想使用03 则 传入excelType参数即可
        EasyExcel.write(fileName, ExcelStudentDTO.class)
                .sheet("模板") //sheet 表名
                .doWrite(data()); //要写入的数据
    }

    
    // 写法2 JDK8+
    @Test
    public void simpleWriteTestXls(){
        //xls文档 最多只能写入六万多(65535)条数据 
        String fileName = "E:/实战/实战-金融宝/excel2023/simpleWrite.xls";
        // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
        // 如果这里想使用03 则 传入excelType参数即可
        EasyExcel.write(fileName, ExcelStudentDTO.class)
                .excelType(ExcelTypeEnum.XLS)
                .sheet("模板") //sheet 表名
                .doWrite(data()); //要写入的数据
    }



    private List<ExcelStudentDTO> data() {
        List<ExcelStudentDTO> list = new ArrayList<ExcelStudentDTO>();
        for (int i = 0; i < 10; i++) { //10 行数据(自定义)
            ExcelStudentDTO data = new ExcelStudentDTO();
            data.setName("字符串" + i);
            data.setBirthday(new Date());
            data.setSalary(0.56);
            list.add(data);
        }
        return list;
    }
}

2、读

参考文档

https://www.yuque.com/easyexcel/doc/read

1、创建监听器

@Slf4j
public class ExcelStudentDTOListener extends AnalysisEventListener<ExcelStudentDTO> {//泛型 - 要读取的实体


    /**
     * 这个每一条数据解析都会来调用
     */
    @SneakyThrows
    @Override
    public void invoke(ExcelStudentDTO data, AnalysisContext context) {
        ArrayList<Object> list = new ArrayList<>();
        //打印输出时间格式转化为String类型
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if(data != null) {
            String date = ft.format(data.getBirthday());
            list.add(data.getName());
            list.add(date);
            list.add(data.getSalary());
        }
        log.info("解析到一条记录:{}", list);
    }


    /**
     * 所有数据解析完成了 都会来调用 -- 收尾工作
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("所有数据解析完成!");
    }
}
2、读取
public class ExcelReadTest {

    /**
     * 最简单的读
     */
    
     // 写法1:xlsx
    @Test
    public void simpleReadXlsx(){
        String fileName = "E:/实战/实战-金融宝/excel2023/simpleWrite.xlsx";
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        // 这里每次会读取3000条数据 然后返回过来 直接调用使用数据就行
        EasyExcel.read(fileName, ExcelStudentDTO.class, new ExcelStudentDTOListener()).sheet().doRead();
    }


    // 写法2:xls
    @Test
    public void simpleReadXls(){
        String fileName = "E:/实战/实战-金融宝/excel2023/simpleWrite.xls";
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        // 这里每次会读取3000条数据 然后返回过来 直接调用使用数据就行
        EasyExcel.read(fileName, ExcelStudentDTO.class, new ExcelStudentDTOListener()).excelType(ExcelTypeEnum.XLS).sheet().doRead();
    }

}

tudentDTO.class, new ExcelStudentDTOListener()).sheet().doRead();
}

// 写法2:xls
@Test
public void simpleReadXls(){
    String fileName = "E:/实战/实战-金融宝/excel2023/simpleWrite.xls";
    // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
    // 这里每次会读取3000条数据 然后返回过来 直接调用使用数据就行
    EasyExcel.read(fileName, ExcelStudentDTO.class, new ExcelStudentDTOListener()).excelType(ExcelTypeEnum.XLS).sheet().doRead();
}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值