使用Java编写导出不确定行数列数数据的工具类

 更新时间:2024年03月15日 16:14:17   作者:IT行业小趴菜  
这篇文章主要为大家详细介绍了如何使用Java编写导出不确定行数列数数据的工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

前言

这是导出不确定行数列数数据的导出工具类,导出的文件直接在浏览器下载,直接全部复制使用,下面有导出的数据样式

一、导出的文件样式

表头不是固定的,可以根据需求,增加表头和与之对应的列数据,详情代码看下面

二、工具类的入参详情

这是表头

这是具体的每一行数据

三、具体代码(直接复制使用)

这个是业务层 使用可以copy到你的业务层方法内,然后进行修修改改。

    public void export(ExportExcelDto dto, HttpServletResponse response) {

        XSSFWorkbook wb = null;
        try {
        	//假设这一是查询数据库拿到的数据
            List<MonitorDataImportQueryVo> vos = new ArrayList<>();

            if (CollectionUtils.isEmpty(vos)) return;
//          文件名根据时间戳生成
            String fileName = DateUtil.currentSeconds() + ".xlsx";
//          表头
            ArrayList<String> header = Lists.newArrayList(READ_HEAD1, READ_HEAD2, READ_HEAD3, READ_HEAD4);
            //时间的动态表头
            List<String> collect = vos.stream()
            	.map(e -> e.getMonitorTime())
            	.distinct()
            	.sorted()
            	.collect(Collectors.toList());
            //放到表头list后面	
            header.addAll(collect);
//          创建一个导出的数据list
            List<List> dataList = Lists.newArrayList();
            
//			根据查询的数据进行分组战后(根据你的业务去处理)
            Map<String, List<MonitorDataImportQueryVo>> map = vos.stream()
            	.collect(Collectors.groupingBy(e -> e.getMonitorNumber()));
//			遍历放入导出数据list里面(根据你的业务去处理)
            for (String s : keySet) {
                List<MonitorDataImportQueryVo> singleData = map.get(s);
                List<String> data = new ArrayList<>();
                data.add(singleData.get(0).getMonitorNumber());
                data.add(singleData.get(0).getMileage());
                data.add(singleData.get(0).getLink());
                data.add(singleData.get(0).getInitialValue());
                for (String thisValue : singleData.stream()
                	.map(e -> e.getThisValue())
                	.collect(Collectors.toList())) {
                    data.add(thisValue);
                }
                dataList.add(data);
            }
//			调用工具类
            wb = ExportExcelUtil.getXSSFWorkbook("监测数据", header, dataList);
            ExportExcelUtil.buildExcelDocument(fileName, wb, response);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != wb) {
                try {
                    wb.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

具体的工具类,无需修改,也可根据需求改改

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * @Description: 导出工具类
 * @Param:
 * @return:
 * @Author: 杨永卓
 * @Date: 2021/9/26 15:47
 */
public class ExportExcelUtil {

    /**
     * @Description: [导出不确定行数列数监测数据]
     * @Param: [sheetName:sheet页名称, headers:第一行表头, data:list里面是每一行数据]
     * @return: org.apache.poi.XSSf.usermodel.XSSFWorkbook
     * @Author: 杨永卓
     * @Date: 2021/9/26 16:11
     */
    public static XSSFWorkbook getXSSFWorkbook(String sheetName, List<String> headers, List<List> dataList) {

        XSSFWorkbook workbook = new XSSFWorkbook();
        //新建工作区并赋名
        XSSFSheet sheet = workbook.createSheet(sheetName);
        XSSFRow row = sheet.createRow(0);

        //设置样式
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        //靠左
        cellStyle.setAlignment(XSSFCellStyle.ALIGN_LEFT);
        //垂直居中
        cellStyle.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
        //设置边框
        cellStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
        cellStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
        //还需要设置其他样式可在此添加

        //找出最大列数:对数据进行排序,获取最长那一行的size
        int max = 0;
        for (List l : dataList) {
            if (l.size() > max) {
                max = l.size();
            }
        }

        XSSFCell cell = null;
        //设置列名
        for (int i = 0; i < max; i++) {
            cell = row.createCell(i);
            cell.setCellValue(headers.get(i));
            cell.setCellStyle(cellStyle);
        }

        for (int i = 0; i < dataList.size(); i++) {
            row = sheet.createRow(i + 1);
            //以max作判断-->实现空的单元格也有边框
            for (int j = 0; j < max; j++) {
                cell = row.createCell(j);
                cell.setCellStyle(cellStyle);
                //防止下标越界
                if (j < dataList.get(i).size()) {
                    //单元格数据类型可自行改变,我这里全部字符串化了
                    cell.setCellValue(dataList.get(i).get(j).toString());
                }
            }
        }

        //列宽自适应
        for (int columnNum = 0; columnNum <= max; columnNum++) {
            int columnWidth = sheet.getColumnWidth(columnNum) / 256;
            for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
                XSSFRow currentRow;
                if (sheet.getRow(rowNum) == null) {
                    currentRow = sheet.createRow(rowNum);
                } else {
                    currentRow = sheet.getRow(rowNum);
                }
                if (currentRow.getCell(columnNum) != null) {
                    XSSFCell currentCell = currentRow.getCell(columnNum);
                    if (currentCell.getCellType() == XSSFCell.CELL_TYPE_STRING) {
                        int length = currentCell.getStringCellValue().getBytes().length;
                        if (columnWidth < length) {
                            columnWidth = length;
                        }
                    }
                }
            }
            sheet.setColumnWidth(columnNum, columnWidth * 256);
        }
        return workbook;
    }
    
	/**
    * @Description: [导出到浏览器]
    * @Param: [fileName, wb, response]
    * @return: void
    *
    * @Author: 杨永卓
    * @Date: 2021/9/26 15:47
    */
    public static void buildExcelDocument(String fileName, Workbook wb, HttpServletResponse response) {
        try {
//            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            // 定义输出类型
            response.setContentType("application/octet-stream");
            // 可自行定义编码格式
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
            //清除jsp编译html文件的空白,防止excel出现空行
            response.flushBuffer();
            //写出
            wb.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

到此这篇关于使用Java编写导出不确定行数列数数据的工具类的文章就介绍到这了,更多相关Java导出数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot实现轻量级动态定时任务管控及组件化的操作步骤

    SpringBoot实现轻量级动态定时任务管控及组件化的操作步骤

    文章介绍了一种在SpringBoot中实现动态定时任务的解决方案,基于COLA架构理论,封装到了组件层,该组件支持类级别和方法级别的定时任务注册,并提供了易用性和扩展性,组件使用Maven形式引入,并且可以通过YAML配置文件进行设置,感兴趣的朋友一起看看吧
    2024-11-11
  • SpringBoot如何实现并发任务并返回结果

    SpringBoot如何实现并发任务并返回结果

    这篇文章主要介绍了SpringBoot如何实现并发任务并返回结果问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • jfinal中stateless模式嵌入shiro验证的实现方式

    jfinal中stateless模式嵌入shiro验证的实现方式

    这篇文章主要介绍了jfinal中stateless模式嵌入shiro验证,今天,我们就来尝试一种通过拦截器来实现的Stateless Jfinal嵌入方式,需要的朋友可以参考下
    2022-06-06
  • 详解SpringBoot之集成Spring AOP

    详解SpringBoot之集成Spring AOP

    本篇文章主要介绍了详解SpringBoot之集成Spring AOP,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 掌握Java拼音转换:pinyin4j库使用方法及应用价值

    掌握Java拼音转换:pinyin4j库使用方法及应用价值

    pinyin4j是一个开源的Java库,用于将汉字转换为拼音,它支持将中文字符转换为标准的全拼形式,并能够处理多音字和声调,本文详细解析pinyin4j库的核心特性、使用方法及其应用价值,感兴趣的朋友一起看看吧
    2025-08-08
  • Java中Set&List的迭代器实现步骤解析

    Java中Set&List的迭代器实现步骤解析

    这篇文章主要介绍了Java中Set&List的迭代器实现步骤解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • springboot2.0和springcloud Finchley版项目搭建(包含eureka,gateWay,Freign,Hystrix)

    springboot2.0和springcloud Finchley版项目搭建(包含eureka,gateWay,Fre

    这篇文章主要介绍了springboot2.0和springcloud Finchley版项目搭建(包含eureka,gateWay,Freign,Hystrix),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • JAVA构造函数不能使用void关键字问题

    JAVA构造函数不能使用void关键字问题

    这篇文章主要介绍了JAVA构造函数不能使用void关键字问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Mybatis mapper.xml使用全局变量的三种实现方法

    Mybatis mapper.xml使用全局变量的三种实现方法

    文章介绍了在Mybatis的Mapper.xml文件中使用全局变量来动态配置数据库库名的实现方案,包括使用mybaits自带全局变量、使用@value和mybatis进行全局变量定义以及使用@value和mybatis进行全局变量定义并减少形参的方案
    2025-02-02
  • 通过实例了解Java Integer类和int的区别

    通过实例了解Java Integer类和int的区别

    这篇文章主要介绍了通过实例了解Java Integer类和int的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03

最新评论