JXLS快速实现报表输出

文章介绍了如何利用JXLS库,基于ApachePOI实现Excel报表的导出,包括制作报表模板,设置文件保护的工具类,以及准备数据和导出的流程。JxlsUtils类提供了静态方法来支持只读和可编辑的Excel导出,通过Controller示例展示了具体的应用场景。
摘要由CSDN通过智能技术生成

目录

制作报表模板

编写文件保护的工具类

准备数据和导出


JXLS是基于POI实现的报表导出功能。

JXLS https://jxls.sourceforge.net/

目前最新版本是:Jxls 2.12.0 !

源码仓库: GitHub - jxlsteam/jxls: Java library for creating Excel reports using Excel templates

制作报表模板

采用标注进行识别,设置表头和列的标签值以及迭代循环处理。

编写文件保护的工具类

原理是在WorkBook.write写入文件流之前设置Sheet的保护机制。

package com.boonya.jxls.examples.utils;

import cn.hutool.core.io.FileUtil;
import org.apache.poi.ss.usermodel.Sheet;
import org.jxls.common.Context;
import org.jxls.transform.Transformer;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.JxlsHelper;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Map;

/**
 * @author Pengjunlin
 * @date 2023/3/17
 */
public class JxlsUtils {

    public static final String PASSWORD = "888888";

    private static String getFileName(String fileName){
        if(StringUtils.isEmpty(fileName)){
            return "未命名数据导出.xlsx";
        }
        if(!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls")){
            fileName = fileName+ ".xlsx";
        }
        return fileName;
    }

    /**
     * 导出到默认路径
     *
     * @param model
     * @param response
     */
    public static void export(String template, String fileUploadPath,String fileName,Map<String, Object> model, HttpServletResponse response) {
        // 设置系统对应的临时路径
        fileName = getFileName(fileName);
        fileUploadPath = fileUploadPath + fileName;
        try (OutputStream os = new FileOutputStream(fileUploadPath)) {
            // 导出到本地路径
            exportToLocalPath(template,null, os, model);
            // 响应下载到客户端
            exportToClient(response, fileUploadPath, fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 导出Excel文件
     *
     * @param template
     * @param password
     * @param fileUploadPath
     * @param fileName
     * @param model
     * @param response
     */
    public static void export(String template,String password,String fileUploadPath,String fileName, Map<String, Object> model, HttpServletResponse response) {
        // 设置系统对应的临时路径
        fileName = getFileName(fileName);
        fileUploadPath = fileUploadPath + fileName;
        try (OutputStream os = new FileOutputStream(fileUploadPath)) {
            // 导出到本地路径
            exportToLocalPath(template,password, os, model);
            // 响应下载到客户端
            exportToClient(response, fileUploadPath, fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Excel导出可编辑
     *
     * @param template
     * @param fileUploadPath
     * @param fileName
     * @param model
     * @param response
     * @throws IOException
     */
    public static void exportByEditable(String template,String fileUploadPath, String fileName, Map<String, Object> model, HttpServletResponse response) throws IOException {
        export(template,null,fileUploadPath,fileName,model,response);
    }

    /**
     * Excel导出只读
     *
     * @param template
     * @param fileUploadPath
     * @param fileName
     * @param model
     * @param response
     * @throws IOException
     */
    public static void exportByReadonly(String template,String fileUploadPath, String fileName, Map<String, Object> model, HttpServletResponse response) throws IOException {
        export(template,PASSWORD,fileUploadPath,fileName,model,response);
    }


    /**
     * 导出文件到客户端
     *
     * @param response
     * @param filePath
     * @param outputFileWithExt
     * @throws IOException
     */
    public static void exportToClient(HttpServletResponse response, String filePath, String outputFileWithExt) throws IOException {
        File file = new File(filePath);
        try {
            while (!file.canRead()){
                Thread.sleep(10);
            }
            // 设置response的Header
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(outputFileWithExt, StandardCharsets.UTF_8.displayName()));
            try (ServletOutputStream servletOutputStream = response.getOutputStream()) {
                FileUtil.writeToStream(file, servletOutputStream);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            FileUtil.del(file);
        }
    }

    /**
     * 导出Excel到本地路径
     *
     * @param template
     * @param password
     * @param os
     * @param model
     * @throws IOException
     */
    public static void exportToLocalPath(String template,String password, OutputStream os, Map<String, Object> model) throws IOException {
        exportExcel(password,JxlsUtils.class.getClassLoader().getResourceAsStream(template),os,model);
    }

    /**
     * 导出Excel自定义
     *
     * @param password
     * @param is
     * @param os
     * @param model
     * @throws IOException
     */
    public static void exportExcel(String password,InputStream is, OutputStream os, Map<String, Object> model) throws IOException {
        Context context = new Context();
        if (model != null) {
            for (String key : model.keySet()) {
                context.putVar(key, model.get(key));
            }
        }
        JxlsHelper jxlsHelper = JxlsHelper.getInstance();
        Transformer transformer = jxlsHelper.createTransformer(is, os);
        PoiTransformer poiTransformer = (PoiTransformer)transformer;
        // 设置是否只读
        if(!StringUtils.isEmpty(password)){
            Iterator<Sheet> sheetIterator = poiTransformer.getWorkbook().sheetIterator();
            while (sheetIterator.hasNext()){
                Sheet sheet = sheetIterator.next();
                if(null != sheet){
                    sheet.protectSheet(password);
                }
            }
        }
        poiTransformer.getTransformationConfig().getExpressionEvaluator();
        jxlsHelper.processTemplate(context, poiTransformer);
    }
}

 准备数据和导出

一个简单的Controller即可

@RestController
@RequestMapping(value = "/export")
@AllArgsConstructor
public class ExportController {

    private final ExcelService excelService;

    @GetMapping(value = "/quoteList")
    @ResponseBody
    public void export(HttpServletRequest request, HttpServletResponse response){
        String filePath = excelService.getTempPath();
        QuoteDataSummary summary = JMockData.mock(QuoteDataSummary.class);
        summary.totalCount();
        Map<String, Object> model = new ConcurrentHashMap<>();
        model.put("header", summary.getHeader());
        model.put("contractData", summary.getRoomList());
        model.put("ungroupData", summary.getUngroupList());
        model.put("groupData", summary.getGroupList());
        try {
            JxlsUtils.exportByReadonly("quoteList.xlsx",filePath,"导出报价清单.xls",model,response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

导出效果:

可以参考:Java 导出Excel利器 JXLS(excel模板配置教程)_HadryChen的博客-CSDN博客

当然我已为大家提供了全部的示例源码: https://gitee.com/researchOfDaily/k8s-demo

低版本的还支持JXLS标签:关于jxls的层级循环研究 - 辜圆圆的个人空间 - OSCHINA - 中文开源技术交流社区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值