easyExcel简单excel导出以及多sheet页导出

Java 程序员在项目上一般会经常遇到解析数据、生成Excel的需求,比较流行的就是Apache poi框架了,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。esayExcel在大数据量的时候是一行一行的解析,不同于POI的一次性解析,这样避免了内存的溢出。

我推荐使用的是2.1.2版本,也是我之前使用的最新版。

官方文档的地址

https://github.com/alibaba/easyexcel 

添加依赖

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>easyexcel</artifactId>

<version>2.1.2</version>

</dependency>

使用方法(模板导出)

写一个dto作为模型,在属性的名称加上注解,作为表头显示在表格中。@ContentRowHeight 单元格行高 @ColumnWidth 单元格列宽 @HeadRowHeight 头的行高@ExcelProperty输出在表格的字段value值代表输出的值index代表是列数(列数是从0开始的所有第0列也就是第一列)@ExcelIgnore不输出在表格中的字段

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.math.BigDecimal;
import java.util.Date;

@ContentRowHeight(20)
@HeadRowHeight(30)
@ColumnWidth(25)
public class PayApplyExcelDto {
    @ExcelProperty(
        value = {"公司名称"},
        index = 0
    )
    private String comName;
    @ExcelProperty(
        value = {"制单部门"},
        index = 1
    )
    private String unitName;
    @ExcelProperty(
        value = {"申请编号"},
        index = 2
    )
    private String applyNum;
    @ExcelProperty(
        value = {"付款类别"},
        index = 3
    )
    private String typeCode;
    @ExcelProperty(
        value = {"付款类型"},
        index = 4
    )
    private String detTypeCode;
    @ExcelProperty(
        value = {"合同号"},
        index = 5
    )
    private String conNum;
    @ExcelProperty(
        value = {"供应商"},
        index = 6
    )
    private String venName;
    @ExcelProperty(
        value = {"实际收款方"},
        index = 7
    )
    @ColumnWidth(30)
    private String actualVenName;
    @ExcelProperty(
        value = {"发票类型"},
        index = 8
    )
    private String invoiceType;
    @ExcelProperty(
        value = {"申请人"},
        index = 9
    )
    private String applicantName;
    @ExcelProperty(
        value = {"申请日期"},
        index = 10
    )
    @DateTimeFormat("yyyy-MM-dd")
    private Date applyDate;
    @ExcelProperty(
        value = {"申请金额"},
        index = 11
    )
    private BigDecimal applyAmt;
    @ExcelProperty(
        value = {"汇率"},
        index = 12
    )
    private BigDecimal rate;
    @ExcelProperty(
        value = {"发票币种"},
        index = 13
    )
    private String invoCurrency;
    @ExcelProperty(
        value = {"付款币种"},
        index = 14
    )
    private String payCurrency;
    @ExcelProperty(
        value = {"实际支付日期"},
        index = 15
    )
    @DateTimeFormat("yyyy-MM-dd")
    private Date actualDate;
    @ExcelProperty(
        value = {"状态"},
        index = 16
    )
    private String status;
    @ExcelProperty(
        value = {"仓储接口状态"},
        index = 17
    )
    private String interStatus;
    @ExcelProperty(
        value = {"付款状态"},
        index = 18
    )
    private String payStatus;
    @ExcelProperty(
        value = {"付款申请状态"},
        index = 19
    )
    private String payInterStatus;
    @ExcelProperty(
        value = {"付款申请接口消息"},
        index = 20
    )
    private String payInterInfo;
    @ExcelProperty(
        value = {"备注"},
        index = 21
    )
    @ColumnWidth(60)
    private String remark;
    @ExcelIgnore
    private String attribute8;
    @ExcelIgnore
    private String attribute10;
    @ExcelIgnore
    private String attribute12;
    @ExcelIgnore
    private String attribute13;
    @ExcelIgnore
    private String attribute14;
    @ExcelIgnore
    private String attribute15;
    @ExcelIgnore
    private Long payId;
    @ExcelIgnore
    private Long comId;
    @ExcelIgnore
    private Long unitId;
    @ExcelIgnore
    private Long cunitId;
    @ExcelIgnore
    private Long venId;
    @ExcelIgnore
    private Long actualPayeeId;
    @ExcelIgnore
    private Long venSiteId;
    @ExcelIgnore
    private String payMethod;
    @ExcelIgnore
    private Long operatorId;
    @ExcelIgnore
    private Date payDate;
    @ExcelIgnore
    private Date postDate;
    @JsonFormat(
        pattern = "yyyy-MM-dd"
    )
    @ExcelIgnore
    private Date applyDateStart;
    @JsonFormat(
        pattern = "yyyy-MM-dd"
    )
    @ExcelIgnore
    private Date applyDateEnd;
    @ExcelIgnore
    private Long acctId;
    @ExcelIgnore
    private Long applicantId;
    @ExcelIgnore
    private String applyDateStr;
    @ExcelIgnore
    private String applyAmtCn;
    @ExcelIgnore
    private String creditNum;
    @ExcelIgnore
    private String interInfo;
    @ExcelIgnore
    private String interNum;
    @ExcelIgnore
    private String payInterNum;
    @ExcelIgnore
    private String finOpinion;
    @ExcelIgnore
    private String unbatchFlag;
    @ExcelIgnore
    private String taxCode;
    @ExcelIgnore
    private BigDecimal taxAmt;
    @ExcelIgnore
    private String invoiceCategory;
    @ExcelIgnore
    private String rateType;
    @ExcelIgnore
    private String acctNum;
    @ExcelIgnore
    private String actualFlag;
    @ExcelIgnore
    private Long bankBranchId;
    @ExcelIgnore
    private String bankName;
    @ExcelIgnore
    private Long postPeopleId;
    @ExcelIgnore
    private BigDecimal sapPayAmt;
    @ExcelIgnore
    private BigDecimal sapPayPamt;
    @ExcelIgnore
    private String bankArea;
    @ExcelIgnore
    private String urgencyDegree;
    @ExcelIgnore
    private String urgencyReason;
    @ExcelIgnore
    private Long busiPeopleId;
    @ExcelIgnore
    private String interAcctNum;
    @ExcelIgnore
    private String conFlag;
    @ExcelIgnore
    private String postPeopleName;
    @ExcelIgnore
    private String busiPeopleName;
    @ExcelIgnore
    private String categoryCode;
    @ExcelIgnore
    private String taxRate;
    @ExcelIgnore
    private String companyFullName;
    @ExcelIgnore
    private String operatorName;
    @ExcelIgnore
    private String costUnitName;
    @ExcelIgnore
    private String venNum;
    @ExcelIgnore
    private String mdmNum;
    @ExcelIgnore
    private String venMdmNum;
    @ExcelIgnore
    private String address;
    @ExcelIgnore
    private String bankAcctNum;
    @ExcelIgnore
    private BigDecimal applyAmtStart;
    @ExcelIgnore
    private BigDecimal applyAmtEnd;
    @ExcelIgnore
    private String costUnitCode;
    @ExcelIgnore
    private String unitCode;
    @ExcelIgnore
    private String bankBranchName;
    @ExcelIgnore
    private String bankBranchNum;
    @ExcelIgnore
    private String typeCodeMeaning;
    @ExcelIgnore
    private String detTypeCodeMeaning;
    @ExcelIgnore
    private String payMethodMeaning;
    @ExcelIgnore
    private String employeeName;
    @ExcelIgnore
    private String positionName;
    @ExcelIgnore
    private String workflowType;
    @ExcelIgnore
    private String currencyName;
    @ExcelIgnore
    private String decription;
    @ExcelIgnore
    private BigDecimal endAmt;
    @ExcelIgnore
    private String endAmtStr;
    @ExcelIgnore
    private String applyAmtStr;
    @ExcelIgnore
    private String taxAmtStr;
    @ExcelIgnore
    private Long conId;
    @ExcelIgnore
    private String extraNum;
    @ExcelIgnore
    private String blNum;
    @ExcelIgnore
    private String invoNum;
    @ExcelIgnore
    private String invoiceTypeMeaning;
    @ExcelIgnore
    private BigDecimal price;
    @ExcelIgnore
    private BigDecimal weight;
    @ExcelIgnore
    private String payDateStr;
    @ExcelIgnore
    private String bankAreaMeaning;
    @ExcelIgnore
    private String approvalDate;
    @ExcelIgnore
    private Long padMillVenId;
    @ExcelIgnore
    private String padMillVenName;
    @ExcelIgnore
    private BigDecimal outGooAmt;
    @ExcelIgnore
    private BigDecimal depoSumAmt;
    @ExcelIgnore
    private BigDecimal finaAmt;
    @ExcelIgnore
    private BigDecimal noReachAmt;
    @ExcelIgnore
    private String nonCancelFlag;
    @ExcelIgnore
    private String hasBill;
    @ExcelIgnore
    private String myApprovalFlag;
    @ExcelIgnore
    private String reAddress;
    @ExcelIgnore
    private String portCertificate;
//get和set方法省略
}

上述的是简单的头结构,如果需要复杂的头结构或者多层头结构可以像下面示例一样添加这样的在value中写出。

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import java.math.BigDecimal;

@ContentRowHeight(20)
@HeadRowHeight(30)
@ColumnWidth(25)
public class BatchSupply {
    @ExcelProperty(
        value = {"在库货源", "姓名"},
        index = 0
    )
    private String comName;
    @ExcelProperty(
        value = {"在库货源", "仓库名称"},
        index = 1
    )
    private String subinvName;
    @ExcelProperty(
        value = {"在库货源", "产地"},
        index = 2
    )
    private String terrName;
    @ExcelProperty(
        value = {"在库货源", "等级"},
        index = 3
    )
    private String ctLevel;
    @ExcelProperty(
        value = {"在库货源", "长度"},
        index = 4
    )
    private String length;
    @ExcelProperty(
        value = {"在库货源", "长度均值"},
        index = 5
    )
    private String lengthMean;
    @ExcelProperty(
        value = {"在库货源", "马值"},
        index = 6
    )
    private String micron;
    @ExcelProperty(
        value = {"在库货源", "马值均值"},
        index = 7
    )
    private String micronMean;
    @ExcelProperty(
        value = {"在库货源", "强力"},
        index = 8
    )
    private String strong;
    @ExcelProperty(
        value = {"在库货源", "强力均值"},
        index = 9
    )
    private String strongMean;
    @ExcelProperty(
        value = {"在库货源", "提单号"},
        index = 10
    )
    private String blNum;
    @ExcelProperty(
        value = {"在库货源", "入库单号"},
        index = 11
    )
    private String entryNum;
    @ExcelProperty(
        value = {"在库货源", "箱号"},
        index = 12
    )
    private String batchNum;
    @ExcelProperty(
        value = {"在库货源", "入库件数"},
        index = 13
    )
    private BigDecimal batchQty;
    @ExcelProperty(
        value = {"在库货源", "销售合同号"},
        index = 14
    )
    private String conNum;
    @ExcelProperty(
        value = {"在库货源", "出库单号"},
        index = 15
    )
    private String outNum;
    @ExcelProperty(
        value = {"在库货源", "出库件数"},
        index = 16
    )
    private BigDecimal outBatchQty;
    @ExcelProperty(
        value = {"在库货源", "在库箱数"},
        index = 17
    )
    private String outStatus;
    @ExcelProperty(
        value = {"在库货源", "在库件数"},
        index = 18
    )
    private BigDecimal wareQty;
    @ExcelProperty(
        value = {"在库货源", "采购合同单价"},
        index = 19
    )
    private BigDecimal conPrice;
    @ExcelProperty(
        value = {"在库货源", "财务入库成本"},
        index = 20
    )
    private BigDecimal finaPrice;
    @ExcelProperty(
        value = {"在库货源", "财务入库成本"},
        index = 21
    )
    private BigDecimal firstUsdPrice;
    @ExcelProperty(
        value = {"在库货源", "初始财务入库成本"},
        index = 22
    )
    private BigDecimal firstRmbPrice;
    @ExcelIgnore
    private String lengthMax;
    @ExcelIgnore
    private String lengthMin;
    @ExcelIgnore
    private String micronMax;
    @ExcelIgnore
    private String micronMin;
    @ExcelIgnore
    private String strongMax;
    @ExcelIgnore
    private String strongMin;
    @ExcelIgnore
    private String terrCode;
    @ExcelIgnore
    private String comCode;
    @ExcelIgnore
    private String subinvId;
    @ExcelIgnore
    private String isBatchFlag;
    @ExcelIgnore
    private Long specId;
}

然后在service层写好逻辑,查询出数据并输出成Excel文件。

@Override
    public void export(IRequest requestContext,HttpServletRequest request, PayApplyExcelDto dto, HttpServletResponse httpServletResponse) throws IOException {
        try {
            String fileName = URLEncoder.encode("付款申请", "UTF-8");
            httpServletResponse.setContentType("application/vnd.ms-excel");
            httpServletResponse.setCharacterEncoding("utf-8");
            httpServletResponse.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(httpServletResponse.getOutputStream(), PayApplyExcelDto.class).autoCloseStream(Boolean.FALSE)
                    .sheet("sheet").doWrite(loadReportData(requestContext,dto));
        } catch (Exception e){
            httpServletResponse.reset();
            httpServletResponse.setContentType("application/json");
            httpServletResponse.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            httpServletResponse.getWriter().println(JSON.toJSONString(map));
        }

    }

这样一个非常简单的excel导出就完成了,这种方法适合于常规的excle导出。能试用很多时候的基本报表导出。如果需要导出多sheet页的文件,只需修改一下业务逻辑即可。如下所示

public void export(HttpServletRequest request, CustInfo custInfo, HttpServletResponse httpServletResponse) throws IOException {
        String fileName = URLEncoder.encode("客商信息表", "UTF-8");
        List<CustInfo> data = this.custInfoMapper.getCustData(custInfo);
        List data1 = this.custInfoMapper.getVendorData(custInfo);

        try {
            httpServletResponse.setContentType("application/vnd.ms-excel");
            httpServletResponse.setCharacterEncoding("utf-8");
            httpServletResponse.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            ExcelWriter excelWriter = EasyExcel.write(httpServletResponse.getOutputStream()).build();
            WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "客户信息").head(CustInfo.class).build();
            WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "供应商信息").head(SupplierInfo.class).build();
            excelWriter.write(data, writeSheet1);
            excelWriter.write(data1, writeSheet2);
            excelWriter.finish();
        } catch (Exception var10) {
            httpServletResponse.reset();
            httpServletResponse.setContentType("application/json");
            httpServletResponse.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + var10.getMessage());
            httpServletResponse.getWriter().println(JSON.toJSONString(map));
        } 
    }

上面就是单sheet页和多sheet页的导出,但是我用的都是模板导出,表头都是固定死的,数据也必须跟模板中的属性对应,所以限制比较大,也不过灵活。

不用模板导出方式

需要自己手写一个方法,然后自己把表头的数据插入进去

 List<List<String>> createHeadList(){
        List<List<String>> head=new ArrayList<List<String>>();
        List<String> headCoulumn1=new ArrayList<String>();
        List<String> headCoulumn2=new ArrayList<String>();
        List<String> headCoulumn3=new ArrayList<String>();
        List<String> headCoulumn4=new ArrayList<String>();
        List<String> headCoulumn5=new ArrayList<String>();
        List<String> headCoulumn6=new ArrayList<String>();

        headCoulumn1.add("客商信息表");headCoulumn1.add("供应商名称");
        headCoulumn2.add("客商信息表");headCoulumn2.add("供应商类别");
        headCoulumn3.add("客商信息表");headCoulumn3.add("地区");
        headCoulumn4.add("客商信息表");headCoulumn4.add("注册省");
        headCoulumn5.add("客商信息表"); headCoulumn5.add("供应商分类");
        headCoulumn6.add("客商信息表"); headCoulumn6.add("信用代码");

        head.add(headCoulumn1);
        head.add(headCoulumn2);
        head.add(headCoulumn3);
        head.add(headCoulumn4);
        head.add(headCoulumn5);
        head.add(headCoulumn6);

        return head;
    }

然后把EasyExcel.writerSheet(1, "供应商信息").head(SupplierInfo.class).build()里面的SupplierInfo.class替换为方法名就好了。

 WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "供应商信息").head(createHeadList() ).build(); 

以上就是两种基本的导出方式以及多sheet页导出方式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342