jxls -excel模板報表生成工具


關於java對於導出excel的工具有很多,如Apache poi、alibaba的easyexcel、jxl、hutool等,但是對於表頭的映射,比較麻煩,如果數據是Map,通過注解的方法就沒法處理表頭。

在不關注如何映射表頭是,想到有模板的方式,那就是用 jxls 工具。

各種工具的效率問題先不討論。

JXLS

jxls是一個簡單的、輕量級的excel導出庫,使用特定的標記在excel模板文件中來定義輸出格式和布局。

jxls是通過預制excel模板,然后通過jxls相應API將我們應用程序的數據結合模板格式輸出到相應的excel文件中,從而形成報表。

 

示例如下:

1、導出如下報表數據

2、excel模板

說明:其中C列和H列,使用了自定義方法;C列方法的作用是將字典code轉換為name文字值,H列方法的作用是計算D->G列的和。

數據如下:

{
    "list": [
        {
            "saleId": 1347929495306274,
            "saleName": "測試業績目標-教務",
            "schoolId": 31,
            "schoolName": "紹興本部校",
            "svList": [
                {
                    "data": {
                        "1": 2,
                        "2": 0,
                        "3": 0,
                        "4": 0
                    },
                    "svType": 1
                },
                {
                    "data": {
                        "1": 1,
                        "2": 0,
                        "3": 0,
                        "4": 0
                    },
                    "svType": 2
                },
                {
                    "data": {
                        "1": 1,
                        "2": 0,
                        "3": 0,
                        "4": 0
                    },
                    "svType": 4
                },
                {
                    "data": {
                        "1": 0.50,
                        "2": 0,
                        "3": 0,
                        "4": 0
                    },
                    "svType": 3
                },
                {
                    "data": {
                        "1": 0.50,
                        "2": 0,
                        "3": 0,
                        "4": 0
                    },
                    "svType": 5
                }
            ]
        },
        {
            "schoolName": "總計",
            "svList": [
                {
                    "data": {
                        "1": 37,
                        "2": 0,
                        "3": 2,
                        "4": 0
                    },
                    "svType": 1
                },
                {
                    "data": {
                        "1": 33,
                        "2": 0,
                        "3": 2,
                        "4": 0
                    },
                    "svType": 2
                },
                {
                    "data": {
                        "1": 38,
                        "2": 0,
                        "3": 2,
                        "4": 0
                    },
                    "svType": 4
                },
                {
                    "data": {
                        "1": 0.89,
                        "2": 0,
                        "3": 1.00,
                        "4": 0
                    },
                    "svType": 3
                },
                {
                    "data": {
                        "1": 1.03,
                        "2": 0,
                        "3": 1.00,
                        "4": 0
                    },
                    "svType": 5
                }
            ]
        }
    ]
}
View Code

3、導出方法代碼片段

項目引入jxls

<!-- jxls -->
<dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls</artifactId>
    <version>2.4.6</version>
</dependency>
<dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls-poi</artifactId>
    <version>1.0.15</version>
</dependency>
View Code

 

該示例以HttpServletResponse response返回文件流,前端直接下載

controller方法:

@RequestMapping("/record/clue/saler")
public void exportSalerResource(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> reqMap) {
    //獲取數據
    PageInfo<Map<String, Object>> pageInfo = clueRecordService.querySalerClueReport(reqMap);
    List<Map<String, Object>> dataList = pageInfo.getList();
    
    Map<String , Object> model=new HashMap<String , Object>();
    model.put("dataList", dataList);
    
    //模板
    String templatePath = "classpath:temp/resource_saler.xlsx";
    //導出文件名稱
    String exportFileName = "咨詢師資源報表.xlsx";
    
    //導出
    JxlsExportUtils.doExcelExport(request, response, model, templatePath, exportFileName);
}
View Code

JxlsExportUtils:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ObjectUtils;
import org.jxls.common.Context;
import org.jxls.expression.JexlExpressionEvaluator;
import org.jxls.transform.Transformer;
import org.jxls.util.JxlsHelper;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.ResourceUtils;

import com.sy.common.conts.CommonConts.BillStateEnum;
import com.sy.common.conts.CommonConts.ClueFromTypeEnum;
import com.sy.common.conts.CommonConts.ClueSV;
import com.sy.common.conts.CommonConts.ClueSourceEnum;
import com.sy.common.conts.CommonConts.OrderStateEnum;
import com.sy.common.conts.CommonConts.PayTypeEnum;
import com.sy.common.conts.CommonConts.UserTypeEnum;

import cn.hutool.core.io.IoUtil;

@Slf4j
public class JxlsExportUtils {
    /**
     * 導出執行方法
     * @param request
     * @param response
     * @param model
     * @param templatePath 模板
     * @param selfFileName 導出文件名
     */
    public static void doExcelExport(HttpServletRequest request, HttpServletResponse response,
                                Map<String, Object> model, String templatePath, String exportFileName) {
        //導出文件名重編碼
        String fileName = FileExportProcess.processFileName(exportFileName, request, response);
        
        response.reset();
        response.setContentType("application/vnd.ms-excel;charset=utf-8"); //設置文件類型
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        
        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            //輸出流為請求響應
            outputStream = response.getOutputStream();
            //模板文件流
            inputStream = getTemplateInputStream(templatePath); //getTemplateStream(templatePath);
            //模板數據構建
            exportExcel(inputStream, outputStream, model);
        } catch (IOException e) {
            log.info("模板填充異常:{}", e);
        } finally {
            //釋放資源
            if (outputStream != null) {
                IoUtil.flush(outputStream);
                IoUtil.close(outputStream);
            }
            if (inputStream != null) {
                IoUtil.close(inputStream);
            }
        }
    }

    /**
     * 模板處理方法
     * @param is
     * @param os
     * @param model
     * @throws IOException
     */
    public static void exportExcel(InputStream is, OutputStream os, Map<String, Object> model) throws IOException {
        if (is == null) {
            log.info("獲取模板異常,模板文件流為空!");
        }
        
        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);
        JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator)transformer.getTransformationConfig().getExpressionEvaluator();
        
        Map<String, Object> funcs = new HashMap<String, Object>();
        funcs.put("utils", new JxlsExportUtils()); // 添加自定義功能,可在excel模板中,可直接使用該自定義對象的方法
        evaluator.getJexlEngine().setFunctions(funcs);
        
        jxlsHelper.processTemplate(context, transformer);
    }

    public static InputStream getTemplateInputStream(String path) throws IOException {
        log.info("模板路徑為:{}", path);
        Resource resource = new ClassPathResource(path);
        InputStream templateInputStream = resource.getInputStream();
        return templateInputStream;
    }
    
    /* 統計量(應該使用枚舉) */
    public String descResourceSV(Integer code) {
        String str = "";
        if (code == 1) {
            str = "新增資源量";
        } else if (code == 2) {
            str = "新增成交量";
        } else if (code == 3){
            str = "新增轉化率";
        } else if (code == 4){
            str = "總成交量";
        } else {
            str = "總轉化率";
        }
        return str;
    }
    
    /* map中value求和 */
    public BigDecimal doSum(Map<String, Object> items) {
        BigDecimal sum = BigDecimal.ZERO;
        if (items != null) {
            for (Entry<String, Object> entry  : items.entrySet()) {
                String value = ObjectUtils.toString(entry.getValue());
                sum = sum.add(new BigDecimal(value));
            }
        }
        return sum;
    }
}
View Code

注意:模板中使用的自定義方法

Map<String, Object> funcs = new HashMap<String, Object>();
funcs.put("utils", new JxlsExportUtils()); // 添加自定義功能,可在excel模板中,可直接使用該自定義對象的方法
evaluator.getJexlEngine().setFunctions(funcs);

4、導出結果

 

標簽語法邏輯還可參考:https://yq.aliyun.com/articles/628239

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM