jxls-poi 以导入的思路做Excel导出

一、分析

        原生的poi导出,最麻烦的就是导出excel样式的设置,十分麻烦。于是有一种想法,就是以导入的思路做导出,就像我们知道的那样,导入excel进内存也必然对象化了,那么我们只要替换对应的业务数据不就可以了吗?

        正如所想的那样,可以实现的,只是有人做到了,也就是有现成的工具类可以使用,说道本文的主角,那就是jxls-poi.看名字也知道必然依赖poi,没错必须依赖poi,只是poi的很多版本存在兼容的问题,略微有点坑。

        jxls是一个简单的、轻量级的excel导出库,使用特定的标记在excel模板文件中来定义输出格式和布局,底层应该是利用反射做的映射,这里本文不针对jxls的具体实现原理做探究,本文重点在于记录一下jxls的使用。(有空再做研究,有空的话或者需要的话)。

        jxls-poi的使用相对来说,是比较简单的,但是其功能是比较强大的。最关键的是对jxls的标记语言的熟悉与使用,当然不熟悉也没关系,因为我也不是很熟悉的。本文记录的使用案例是基本对导出excel来说是通用的,多sheet页,当然还没用多行遍历集合数据。重在在使用中进行摸索,不采坑不进步~

二、导出模板

批注的使用

//指定模板的范围

jx:area(lastCell="L56") 

//items对导出数据进行遍历,var遍历出的每一项数据,lastCell指定模板的范围,multisheet多sheet的对应sheet名称集合

jx:each(items="aiFormulaResultData", var="data", lastCell="L56" multisheet="aiFormulaResultDataSheetNames")

导出模板.xlsx
指定模板的范围

三、业务代码

@RequestMapping("/downloadExcel.action")

public void downloadExcel(HttpServletRequest request, HttpServletResponse response)throws IOException {

    List data =dataService.getData();

    List dataSheetNames =new ArrayList<>(data .size());

    //sheetName

    String templateSheetName1 = ConstVar.SHEET_DATA1;

    String templateSheetName2 = ConstVar.SHEET_DATA2;

    for (int i =0; i < data.size(); i++) {

        dataSheetNames.add((String)data.get(i).get("code"));

    }

    Map bindDataMap =new HashMap<>();

    bindDataMap.put("aiChemicalDataSheetNames", aiChemicalDataSheetNames);

    bindDataMap.put("aiChemicalDataList", chemicalData);

    //获取获取模板  国际化

    String templateFileName = RequestContextUtils.getLocale(request).equals(Locale.SIMPLIFIED_CHINESE) ? ConstVar.AI_EXCEL_CHINESE_NAME : ConstVar.AI_EXCEL_ENGLISH_NAME;

    File tempTargetFile =new File(CommonUtil.getGuid() +".xlsx");

    InputStream inputStreamClassPath =null;

    InputStream inputStream =null;

try {

    inputStreamClassPath =new ClassPathResource("downloadTemplateExcel/" + templateFileName).getInputStream();

    //读取模板-写入数据-删除模板sheet

    JxlsExportTemplateExcelUtils.exportExcelAndDeleteTemplateSheet(inputStreamClassPath, tempTargetFile, bindDataMap, templateSheetName1, templateSheetName2);

    inputStream =new FileInputStream(tempTargetFile);

    //设置response头信息

    response.reset();

    String title = CommonUtil.encodingFileName(I18nUtils.getMessage("chemical.pdfTitleName"));

    response.setContentType("application/octet-stream");

    response.setHeader("Content-Length", String.valueOf(inputStream.available()));

    response.setHeader("Content-Disposition","attachment;filename=" + title + CommonUtil.getCurrentDate() +".xlsx");

    OutputStream out = response.getOutputStream();

    //创建缓冲区

    FileCopyUtils.copy(new BufferedInputStream(inputStream),new BufferedOutputStream(out));

}catch (Exception e) {

    logger.error("下载EXCEL出现异常 " + CommonUtil.getExceptionDetail(e));

}finally {

    if (inputStream !=null) {

        inputStream.close();

    }

    if (inputStreamClassPath !=null) {

        inputStreamClassPath.close();

    }

    if (tempTargetFile !=null && tempTargetFile.exists()) {

        tempTargetFile.delete();

    }

}

}

四、工具类

JxlsExportTemplateExcelUtils

//对外提供

public static void exportExcelAndDeleteTemplateSheet(InputStream templateFileInputStreamn, File tempTargetFile, Map bindDataMap, String... templateSheetNames)throws FileNotFoundException, IOException {

exportExcel(templateFileInputStreamn, tempTargetFile, bindDataMap, templateSheetNames);

}

//多种重载

private static void exportExcel(InputStream is, File out, Map model, String... sheetNames)throws IOException {

    OutputStream os =new FileOutputStream(out);

Context context = PoiTransformer.createInitialContext();

if (model !=null) {

for (Map.Entry entry : model.entrySet()) {

context.putVar(entry.getKey(), entry.getValue());

}

}

JxlsHelper jxlsHelper = JxlsHelper.getInstance();


//必须要这个,否者表格函数统计会错乱

   jxlsHelper.getInstance().setUseFastFormulaProcessor(false).processTemplate(context, jxlsHelper.createTransformer(is, os));

//删除对应的模板sheet页

    deleteSheet(out, sheetNames);

}

//删除对应的模板sheet页

public static void deleteSheet(File file, String... sheetNames) {

try {

FileInputStream fis =new FileInputStream(file);

XSSFWorkbook wb =new XSSFWorkbook(fis);

fileWrite(file, wb);

//删除Sheet

        for (String sheetName : sheetNames) {

wb.removeSheetAt(wb.getSheetIndex(sheetName));

}

fileWrite(file, wb);

fis.close();

}catch (Exception e) {

//e.printStackTrace();

    }

}

五、maven依赖

<!--项目中已使用poi,此处排除-->

<dependency>

<groupId>org.jxls</groupId>

<artifactId>jxls-poi</artifactId>

<version>1.1.0</version>

<exclusions>

<exclusion>

<groupId>org.apache.poi</groupId>

<artifactId>poi</artifactId>

</exclusion>

<exclusion>

<groupId>org.apache.poi</groupId>

<artifactId>poi-ooxml</artifactId>

</exclusion>

</exclusions>

</dependency>

<!--POI-->

<dependency>

<groupId>org.apache.poi</groupId>

<artifactId>poi</artifactId>

<version>3.17</version>

</dependency>

<dependency>

<groupId>org.apache.poi</groupId>

<artifactId>poi-ooxml</artifactId>

<version>3.17</version>

</dependency>

六、总结

整体来说,是相对简单的,思路与想法很重要,只要你能想到的,一般就已经有人做到了,而且做得还不错。但是需要在实践中发现问题,解决问题。

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

推荐阅读更多精彩内容

  • 我们在做这个项目的时候,需要导出一个excel文件,所以我就想到了使用poi导出数据 下面把代码贴出来,供大家参考...
    Harry小哥哥阅读 2,116评论 0 6
  • 首先添加依赖。 <!--文件上传组件--> <dependency> <groupId>commons-fileu...
    散过丶阅读 1,044评论 0 2
  • Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Ja...
    玩味Orz阅读 2,575评论 0 0
  • java导出excel表格: 1、导入jar包 <dependency><groupId>org.apache.p...
    邱实_b532阅读 1,847评论 0 0
  • A约我在学校的咖啡厅见面,我到那里的时候他已经坐在那里了,正不安的喝着茶。 我坐到他对面时他突然疯了一...
    50ml阅读 260评论 1 1