ssm poi导出数据到excel文件中,并不在服务器上生成excel文件

本文详细介绍了一种在Java中将数据导出至Excel的方法,包括定义导出逻辑、使用自定义工具类处理空指针异常、调用Excel工具类进行数据导出,以及在Controller层实现接口调用。文章提供了完整的代码示例,展示了如何从service层获取数据并将其转换为Excel文件格式,同时确保了数据的安全性和服务端资源的有效利用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们直接上代码:

首先是service层,首先定义一个方法,并在实现类中写文件导出的逻辑:

void export(ExportErrorPartDataReq exportReq, ServletOutputStream out);

serviceImpl:

@Override
    public void export(ExportErrorPartDataReq exportReq, ServletOutputStream out) {

        SptBrandTempExample example = new SptBrandTempExample();
        SptBrandTempExample.Criteria criteria = example.createCriteria();
        criteria.andUuidEqualTo(exportReq.getUuid());
        criteria.andIsErrorEqualTo(0);
        List<SptBrandTemp> sptBrandTempList = sptBrandTempMapper.selectByExample(example);

        String [] title = new String[16];
        title[0] = "aaa";
        title[1] = "bbb";
        title[2] = "ccc";
        title[3] = "ddd";
        title[4] = "eee";
        title[5] = "fff";
        title[6] = "ggg";
        title[7] = "hhh";
        title[8] = "iii";
        title[9] = "jjj";
        title[10] = "kkk";
        title[11] = "lll";
        title[12] = "mmm";
        if(DefaultEnum.SPT_ENUM_BRNAD.getKey() == exportReq.getPartType()){
            title[13] = "nnn";
            title[14] = "ooo";
            title[15] = "ppp";
        }

        List<List<String>> rows = null;
        try {
            rows = new LinkedList<>();
            for (SptBrandTemp sptBrandTemps : sptBrandTempList) {
                List<String> row = new LinkedList<>();
                // 配件类型
                row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getCarBrandName()));
                row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getFactoryName()));
                row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getOeNum()));
                row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getOeNumFormat()));
                row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getOeNumExt()));
                row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getOeName()));
                row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getCatPartName()));
                row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getCatPartCode()));
                row.add(DefaultEnum.getEnum(exportReq.getPartType()).getName());
                row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getPartRemark()));
                row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getNewOeNumber()));
                row.add("adaptModelJY");
                row.add("adaptModel");
                if(DefaultEnum.SPT_ENUM_BRNAD.getKey() == exportReq.getPartType()){
                    row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getPartFormat()));
                    row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getPartBrandName()));
                    row.add(NotEmptyUtil.notEmptyString(sptBrandTemps.getFactoryCode()));
                }
                logger.info("sptBrandTemps---> {}" + sptBrandTemps.toString());
                logger.info(row.size() + "个元素");
                rows.add(row);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            HSSFWorkbook wk = ExcelUtil.writeListToExcel("信息", title, rows);
            wk.write(out);
            // out流不是自己创建的,不用关闭
            out.flush();
        } catch (IOException e) {
            logger.error("写excel出错 {}", e);
        }

        return;
    }

为了预防空指针异常,我们自定义一个工具类,添加判空处理,这个大家可以根据自己的业务需要自己定义相应的工具类,目的呢,第一就是进行数据判空或校验或者其他处理,其次调用工具类可以使代码更加整洁美观,可读性方面也会好一些:

public class NotEmptyUtil {


    public static String notEmptyString (String in){
        if(StringUtil.isNotEmptyOrNull(in)){
            return  in;
        }else{
            return "-";
        }
    }

    public static Integer notzeroInt(Integer in){
        if(!in.equals(0)){
            return in;
        }else{
            return 0;
        }
    }

然后是调用相应的excel工具类:

public class ExcelUtil {

    /**
     * 导出数据
     *
     * @param sheetName sheet
     * @param heads     标题
     * @param dataList  数据
     * @return
     */
    public static HSSFWorkbook writeListToExcel(String sheetName, String[] heads, List<List<String>> dataList) {

        if (heads == null || dataList == null || dataList.isEmpty()) {
            return null;
        }

        // 创建工作簿对象
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 创建工作表
        HSSFSheet sheet = workbook.createSheet(sheetName);

        /** 写标题 (第一行) */
        HSSFRow headRow = sheet.createRow(0);
        for (int i = 0, len = heads.length; i < len; i++) {
            // 创建单元格
            HSSFCell cell = headRow.createCell(i);
            // 设置单元格的值
            cell.setCellValue(heads[i]);
        }

        /** 写数据 */
        int count = 0;
        for (List<String> list : dataList) {
            // 行从第一行开始,第0行是标题
            count++;
            // 创建行
            HSSFRow row = sheet.createRow(count);
            int i = 0;
            for (String str : list) {
                // 创建单元格
                HSSFCell cell = row.createCell(i);
                // 设置单元格的值
                cell.setCellValue(str);
                i++;
            }
        }

        return workbook;
    }

    public static List<String> writeExcel(List<List<String>> sheetData, String fileUrl, long fileLimit) {
        //在内存中保持100条, 超过的数据放到硬盘中
        SXSSFWorkbook wb = new SXSSFWorkbook(100);
        wb.setCompressTempFiles(true); //将磁盘中的临时文件压缩优化,否则会很大
        Sheet sh = wb.createSheet("Sheet1");
        printRowValue(sheetData, sh, 0, sheetData.size());
        List<String> res = null;
        try {
            res = writeFileOutputStream(sheetData, fileUrl, wb, fileLimit);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            wb.dispose();//删除临时文件
        }
        return res;
    }

    private static List<String> writeFileOutputStream(List<List<String>> sheetData, String fileUrl, SXSSFWorkbook wb, long fileLimit) throws IOException {
        File file=new File(fileUrl);
        //如果父目录不存在,则创建
        if (!file.getParentFile().exists()) {
            if(!file.getParentFile().mkdirs()){
                return null;
            }
        }
        FileOutputStream out = new FileOutputStream(fileUrl);
        wb.write(out);
        out.close();
        if(new File(fileUrl).length()>=20*1020*1024){
            return null;
        }

        List<String> fileUrls = new ArrayList<>();
        if(fileLimit != 0){//按照文件大小限制分片
            int burstSize = new Long(new File(fileUrl).length()/fileLimit+1).intValue();
            int increment = sheetData.size()/burstSize+1;
            String preUrl = file.getParent()+File.separator+"数据", sufUrl = ".xlsx", resUrl = "";
            for(int i=0; i<burstSize; i++){
                resUrl = preUrl + (i+1) + sufUrl;
                fileUrls.add(resUrl);
                writeExcelSplit(sheetData, resUrl,i*increment, increment);
            }
            file.delete();
        }else{
            fileUrls.add(fileUrl);
        }
        return fileUrls;
    }

    /**
     *
     * @param sheetData 需要导出的数据
     * @param fileUrl 导出的文件url
     * @param offset 数据开始的偏移量
     * @param limit 数据限制条数
     */
    public static void writeExcelSplit(List<List<String>> sheetData, String fileUrl, int offset, int limit) {
        //在内存中保持100条, 超过的数据放到硬盘中
        SXSSFWorkbook wb = new SXSSFWorkbook(100);
        wb.setCompressTempFiles(true); //将磁盘中的临时文件压缩优化,否则会很大
        Sheet sh = wb.createSheet("Sheet1");
        printRowValue(sheetData, sh, offset, limit);
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(fileUrl);
            wb.write(out);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            wb.dispose();//删除临时文件
        }
    }

    private static void printRowValue(List<List<String>> sheetData, Sheet sh, int offset, int limit) {
        int size = Math.min(offset+limit, sheetData.size());
        for (int rownum = offset; rownum < size; rownum++) {
            Row row = sh.createRow(rownum-offset);
            List<String> rowValue = sheetData.get(rownum);
            for (int cellnum = 0; cellnum < rowValue.size(); cellnum++) {
                Cell cell = row.createCell(cellnum);
                cell.setCellValue(rowValue.get(cellnum));
            }
        }
    }
}

最后面试controller层,调用service方法,一般使用GET方式请求接口:

/**
     *  导出数据
     */
    @RequestMapping(value = "import/errorlist", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public DataResult export(HttpServletRequest request, @Valid ExportErrorPartDataReq exportReq, BindingResult bindingResult, HttpServletResponse response) {
        DataResult res = new DataResult();

        logger.info("request params : {}" , JSONObject.toJSON(exportReq));
        try {
            String fileName = "导出-" + DateUtil.getCurrentDateString();
            response.reset();
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xls");
            response.setContentType("application/vnd.ms-excel; charset=utf-8");
            ServletOutputStream out = response.getOutputStream();
            carAllPartStatInfoService.export(exportReq,out);
        } catch (IOException e) {
            e.printStackTrace();
        }

        logger.info("result params : {}" , JSONObject.toJSON(res));
        return res;
    }

到这里一个数据导出到excel文件,并下载excel文件接口就这样完成了,很简单,大家拿来直接按照自己的数据导出模板套着用就可以了,这里源码就不提供了,因为设计到公司的一些数据,相信大家应该看的懂把。这种方式导出的excel文件,是不会再服务端生成一个excel文件,在通过输出流下载文件的。在日常的生产环境中,也是不允许在服务端生成文件的,这一点大家要注意一下。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值