`
jamie.wang
  • 浏览: 348764 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

用jXLS和poi导出Excel

    博客分类:
  • Java
阅读更多

apache的poi提供了支持MS Office文档操作的java API。jXLS则是基于poi提供了支持Excel模版操作的API。

jXLS的主页是:http://jxls.sourceforge.net,似乎国内不能访问,需要代理。

 

下面是一些例子,以及我对导出到多个sheet的一个封装。

先定义一个模版:



 这里的jxls tag和JSP的tag很像,varStatus是本次循环变量。

jxls提供了一个最简单的接口:

void net.sf.jxls.transformer.XLSTransformer.transformXLS(String srcFilePath, Map beanParams, String destFilePath) throws ParsePropertyException, IOException, InvalidFormatException

 

        String srcFilePath = "E:\\tmp\\template-simple.xlsx";
        Map<String, Object> beanParams = new HashMap<String, Object>();
        List<VM> vms = new ArrayList<VM>();
        VM vm = new VM();
        vm.setName("我的CENTOS");
        vm.setPrice(103);
        vm.setScale("2CPU, 2G MEM, 2T DISK");
        vm.setCreated(new Date());
        vms.add(vm);
        VM vm2 = new VM();
        vm2.setName("my-ubuntu");
        vm2.setPrice(200);
        vm2.setScale("1CPU, 3G MEM, 1T DISK");
        vm2.setCreated(new Date());
        vms.add(vm2);
        beanParams.put("vms", vms);

        String destFilePath = "E:\\tmp\\simple.xlsx";

        XLSTransformer transformer = new XLSTransformer();
        transformer.transformXLS(srcFilePath, beanParams, destFilePath);

执行结果:


 

jXLS提供了很多方法,支持很复杂的表格生成。

但如果要指定在一个sheet最大行数,不是很方便,我包装了一个util方法:

package org.jamee.demo.poiexcel;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.jxls.transformer.XLSTransformer;

import org.apache.poi.ss.usermodel.Workbook;

public class ExcelUtil {
    private static final String DEFAULT_SHEET_NAME = "sheet";

    /**
     * 导出无动态表头的Excel文件
     * <p>
     * 参考重载的有动态表头注释
     * </p>
     * @param destOutputStream
     * @param templateInputStream
     * @param data
     * @param dataKey
     * @param maxRowPerSheet
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void generateExcelByTemplate(OutputStream destOutputStream, 
            InputStream templateInputStream, 
            List data, String dataKey,
            int maxRowPerSheet) throws Exception {
        generateExcelByTemplate(destOutputStream,
                templateInputStream,
                null, null,
                data, dataKey,
                maxRowPerSheet);
    }

    /**
     * 通过Excel模版生成Excel文件
     * <p>
     * 创建Excel模版,变量类似JSP tag风格。
     * 例如:
     * <ul>
     * <li>无动态表头
     * <pre>
     * 序号   名称  规格  创建时间    价格
     * &lt;jx:forEach items="${vms}" var="vm"&gt;
     * ${vm.id} ${vm.name} ${vm.scale} ${vm.created} ${vm.price}
     * &lt;/jx:forEach&gt;
     * </pre>
     * </li>
     * <li>有动态表头
     * <pre>
     * 项目/数量/时间    &lt;jx:forEach items="${dates}" var="date"&gt;    ${date} &lt;/jx:forEach&gt;
     * &lt;jx:forEach items="${itemsx}" var="item"&gt;            
     * ${item.name}    &lt;jx:forEach items="${item.counts}" var="count"&gt; ${count}    &lt;/jx:forEach&gt;
     * &lt;/jx:forEach&gt;           
     * </pre>
     * </li>
     * </ul>
     * 调用该方法则生成对应的Excel文件。
     * </p>
     * <p>
     * 注意:dataKey不能是items, items是保留字,如果用items则会提示:Collection is null并抛出NullPointerException
     * </p>
     * @param destOutputStream Excel输出流
     * @param templateInputStream Excel模版输入流
     * @param header 动态表头
     * @param headerKey 表头的变量
     * @param data 数据项
     * @param dataKey 数据项变量
     * @param maxRowPerSheet 每个sheet最多行数
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void generateExcelByTemplate(OutputStream destOutputStream, 
            InputStream templateInputStream, 
            List header, String headerKey,
            List data, String dataKey,
            int maxRowPerSheet) throws Exception {

        List<List> splitData = null;
        @SuppressWarnings("unchecked")
        Map<String, List> beanMap = new HashMap();
        List<String> sheetNames = new ArrayList<String>();
        if (data.size() > maxRowPerSheet) {
            splitData = splitList(data, maxRowPerSheet);
            sheetNames = new ArrayList<String>(splitData.size());
            for (int i = 0; i < splitData.size(); ++i) {
                sheetNames.add(DEFAULT_SHEET_NAME  + i);
            }
        } else {
            splitData = new ArrayList<List>();
            sheetNames.add(DEFAULT_SHEET_NAME + 0);
            splitData.add(data);
        }
        if (null != header) {
            beanMap.put(headerKey, header);
        }
        XLSTransformer transformer = new XLSTransformer();
        Workbook workbook = transformer.transformMultipleSheetsList(
                templateInputStream, splitData, sheetNames, dataKey, beanMap, 0);
        workbook.write(destOutputStream);
    }


    /**
     * 导出无动态表头的Excel文件,目标文件和模版文件均为文件路径
     * <p>
     * 参考重载的有动态表头注释
     * </p>
     * @param destFilePath
     * @param templateFilePath
     * @param data
     * @param dataKey
     * @param maxRowPerSheet
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void generateExcelByTemplate(String destFilePath, 
            String templateFilePath, 
            List data, String dataKey, int maxRowPerSheet) throws Exception {
        generateExcelByTemplate(destFilePath, templateFilePath, null, null, data, dataKey, maxRowPerSheet);
    }

    /**
     * 导出有动态表头的Excel文件,目标文件和模版文件均为文件路径
     * <p>
     * 参考重载的有动态表头注释
     * </p>
     * @param destFilePath
     * @param templateFilePath
     * @param header
     * @param headerKey
     * @param data
     * @param dataKey
     * @param maxRowPerSheet
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void generateExcelByTemplate(String destFilePath, 
            String templateFilePath, 
            List header, String headerKey,
            List data, String dataKey, int maxRowPerSheet) throws Exception {
        generateExcelByTemplate(new FileOutputStream(destFilePath),
                new FileInputStream(templateFilePath),
                header, headerKey,
                data, dataKey, maxRowPerSheet);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private static List<List> splitList(List data, int maxRowPerSheet) {
        List<List> splitData = new ArrayList<List>();
        List sdata = null;
        for (int i = 0; i < data.size(); ++i) {
            if (0 == i % maxRowPerSheet) {
                if (null != sdata) {
                    splitData.add(sdata);
                }
                sdata = new ArrayList(maxRowPerSheet);
            }
            sdata.add(data.get(i));
        }
        if (0 != maxRowPerSheet % data.size()) {
            splitData.add(sdata);
        }

        return splitData;
    }
}

简单

用法:

        List<VM> vms = new ArrayList<VM>();
        for (int i = 0; i < 21; ++i) {
            VM vma = new VM();
            vma.setId(i);
            vma.setName("我的CENTOS" + i);
            vma.setPrice(103);
            vma.setScale("2CPU, 2G MEM, 2T DISK");
            vma.setCreated(new Date());
            vms.add(vma);
        } 
ExcelUtil.generateExcelByTemplate("E:\\tmp\\ex-sample.xlsx", "E:\\tmp\\template-simple.xlsx", vms, "vms", 10);

 运行结果:



 可见有3个sheet生成。

 

接口中的动态表头是指表头是数据项中的字段,例如:日期,项目等。

例如下面这个模版:



 调用示例:

         List<String> dates = new ArrayList<String>();
        int maxDates = 8;
        for (int i = 0; i < maxDates ; ++i) {
            dates.add("2013-08-1" + i);
        }
        List<ItemCount> itemCounts = new ArrayList<ItemCount>();
        for (int i = 0; i < 82; ++i) {
            ItemCount ic = new ItemCount();
            List<Integer> counts = new ArrayList<Integer>();
            for (int j = 0; j < maxDates; ++j) {
                counts.add(j);
            }
            ic.setCounts(counts);
            ic.setName("item" + i);
            itemCounts.add(ic);
        }
        ExcelUtil.generateExcelByTemplate("E:\\tmp\\ex-cpx.xlsx", 
                "E:\\tmp\\template-matrix.xlsx", dates, "dates", itemCounts, "itemsx", 12);

 结果:



 

  • 大小: 29.1 KB
  • 大小: 19.4 KB
  • 大小: 4.7 KB
  • 大小: 17.3 KB
  • 大小: 13.7 KB
分享到:
评论
7 楼 xuxiaoyinliu 2016-09-04  
chen_bing8 写道
你好,为什么我用你的demo运行后报异常了?
大侠能否帮我看下?急。。。。。非常感谢


log4j:WARN No appenders could be found for logger (net.sf.jxls.transformer.SheetTransformer).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.NullPointerException
at net.sf.jxls.tag.ForEachTag.selectCollectionDataToProcess(ForEachTag.java:388)
at net.sf.jxls.tag.ForEachTag.processOneRowTag(ForEachTag.java:239)
at net.sf.jxls.tag.ForEachTag.process(ForEachTag.java:183)
at net.sf.jxls.transformer.TagRowTransformer.transform(TagRowTransformer.java:32)
at net.sf.jxls.transformer.SheetTransformer.transformSheet(SheetTransformer.java:88)
at net.sf.jxls.transformer.XLSTransformer.transformWorkbook(XLSTransformer.java:248)
at net.sf.jxls.transformer.XLSTransformer.transformMultipleSheetsList(XLSTransformer.java:371)
at org.jamee.demo.poiexcel.ExcelUtils.generateExcelByTemplate(ExcelUtils.java:97)
at org.jamee.demo.poiexcel.ExcelUtils.generateExcelByTemplate(ExcelUtils.java:141)
at org.jamee.demo.poiexcel.POIExcelDemo.testExcelUtilsCpx(POIExcelDemo.java:266)
at org.jamee.demo.poiexcel.POIExcelDemo.main(POIExcelDemo.java:232)


作者已经在上面已经说了,只不过他没有在文件中修改;
“注意:dataKey不能是items, items是保留字,如果用items则会提示:Collection is null并抛出NullPointerException ”
所以修改template-matrix-bak.xls文件中的${items}为其他的名称并且与程序中的dataKey对应起来就可以了,比如修改为${vm},将方法testExcelUtilsCpx()中的
        ExcelUtils.generateExcelByTemplate("E:\\tmp\\ex-cpx.xlsx",
                "E:\\tmp\\template-matrix-bak.xlsx", dates, "dates", itemCounts, "vm", 12);倒数第二个参数也修改为vm就可以了
6 楼 zi_wu_xian 2016-08-29  
java用poi和jxl对excel的读取还好,如果修改文件的话,会破坏文件的格式,甚至excel自己都不能打开了。用PageOffice不管读取还是修改excel文件中的数据都不会破坏excel文件的格式,因为PageOffice调用的VBA接口,推荐试试
5 楼 sqq920556218 2014-12-16  
很有用,也没有报错,正在研究应用于项目
4 楼 丿Fee丶腳歩 2014-09-19  
chen_bing8 写道
你好,为什么我用你的demo运行后报异常了?
大侠能否帮我看下?急。。。。。非常感谢


log4j:WARN No appenders could be found for logger (net.sf.jxls.transformer.SheetTransformer).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.NullPointerException
at net.sf.jxls.tag.ForEachTag.selectCollectionDataToProcess(ForEachTag.java:388)
at net.sf.jxls.tag.ForEachTag.processOneRowTag(ForEachTag.java:239)
at net.sf.jxls.tag.ForEachTag.process(ForEachTag.java:183)
at net.sf.jxls.transformer.TagRowTransformer.transform(TagRowTransformer.java:32)
at net.sf.jxls.transformer.SheetTransformer.transformSheet(SheetTransformer.java:88)
at net.sf.jxls.transformer.XLSTransformer.transformWorkbook(XLSTransformer.java:248)
at net.sf.jxls.transformer.XLSTransformer.transformMultipleSheetsList(XLSTransformer.java:371)
at org.jamee.demo.poiexcel.ExcelUtils.generateExcelByTemplate(ExcelUtils.java:97)
at org.jamee.demo.poiexcel.ExcelUtils.generateExcelByTemplate(ExcelUtils.java:141)
at org.jamee.demo.poiexcel.POIExcelDemo.testExcelUtilsCpx(POIExcelDemo.java:266)
at org.jamee.demo.poiexcel.POIExcelDemo.main(POIExcelDemo.java:232)


也碰到了,只知道是jar包冲突,暂时不知道怎么解决,有大虾解决的吗?用的poi3.9和jxls的1.0.5
3 楼 jamie.wang 2014-08-12  
m33707 写道
请教下,你的代码能正常运行,但日期结果是数字?
你的截图是格式化的日期


规格                 创建时间 价格
2CPU, 2G MEM, 2T DISK 41782.42176 103
2CPU, 2G MEM, 2T DISK 41782.42176 103
2CPU, 2G MEM, 2T DISK 41782.42176 103


应该是excel的显示问题
2 楼 m33707 2014-05-23  
请教下,你的代码能正常运行,但日期结果是数字?
你的截图是格式化的日期


规格                 创建时间 价格
2CPU, 2G MEM, 2T DISK 41782.42176 103
2CPU, 2G MEM, 2T DISK 41782.42176 103
2CPU, 2G MEM, 2T DISK 41782.42176 103

1 楼 chen_bing8 2014-04-26  
你好,为什么我用你的demo运行后报异常了?
大侠能否帮我看下?急。。。。。非常感谢


log4j:WARN No appenders could be found for logger (net.sf.jxls.transformer.SheetTransformer).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" java.lang.NullPointerException
at net.sf.jxls.tag.ForEachTag.selectCollectionDataToProcess(ForEachTag.java:388)
at net.sf.jxls.tag.ForEachTag.processOneRowTag(ForEachTag.java:239)
at net.sf.jxls.tag.ForEachTag.process(ForEachTag.java:183)
at net.sf.jxls.transformer.TagRowTransformer.transform(TagRowTransformer.java:32)
at net.sf.jxls.transformer.SheetTransformer.transformSheet(SheetTransformer.java:88)
at net.sf.jxls.transformer.XLSTransformer.transformWorkbook(XLSTransformer.java:248)
at net.sf.jxls.transformer.XLSTransformer.transformMultipleSheetsList(XLSTransformer.java:371)
at org.jamee.demo.poiexcel.ExcelUtils.generateExcelByTemplate(ExcelUtils.java:97)
at org.jamee.demo.poiexcel.ExcelUtils.generateExcelByTemplate(ExcelUtils.java:141)
at org.jamee.demo.poiexcel.POIExcelDemo.testExcelUtilsCpx(POIExcelDemo.java:266)
at org.jamee.demo.poiexcel.POIExcelDemo.main(POIExcelDemo.java:232)

相关推荐

    jxls-poi导出excel示例代码文件

    4. **导出Excel**:最后,`jxls-poi`会生成一个新的Excel文件,其中包含了从JSON数据填充后的内容。你可以选择保存到本地或者直接通过HTTP响应发送给用户下载。 具体代码示例可能如下: ```java import org.jxls....

    通过jxls和poi导出excel的dome

    在"通过jxls和poi导出excel的dome"中,我们将看到以下核心步骤: 1. **创建Excel模板**:首先,你需要设计一个Excel模板,包含所有所需的样式和布局。模板中的某些区域将被标记为数据注入点,这些通常用特定的jxls...

    jxls和poi导出excel的架包

    1. **使用Apache POI导出Excel** - 创建Workbook对象:`HSSFWorkbook`(用于Excel 2003及以下版本)或`XSSFWorkbook`(用于Excel 2007及以上版本)。 - 添加Sheet对象到Workbook中,每个Sheet代表Excel的一张工作...

    使用 jxls2.X 导出excel文件

    "使用jxls2.X导出Excel文件"的主题涉及了如何利用Java来生成和操作Excel文档,尤其适用于需要动态生成内容的场景。在这个项目案例中,开发者使用了jxls库的最新版本(jxls2),它是一个强大的工具,能够帮助程序员将...

    jxls使用模板实现导出excel!

    jxls是一个强大的工具,它允许我们使用Apache POI库的功能,但通过使用JSP标签和简单的模板来简化Excel文件的创建过程。下面将详细介绍jxls如何利用模板来实现Excel的导出。 1. **jxls概述**: jxls是一个Java库,...

    使用JXLS+Excel模板制作灵活的excel导出

    5. **导出Excel**:最后,生成填充后的Excel文件,可以保存到本地或作为HTTP响应发送给用户。 在`example-jxls-main`这个压缩包中,可能包含了以下内容: - 一个或多个示例Excel模板文件,展示了如何设置单元格样式...

    jxls利用模板生成excel文件

    3. 编写Java代码:定义数据模型,使用`jxls`提供的API加载模板,绑定数据,最后导出Excel文件。 4. 运行和测试:运行代码,生成的Excel文件将按照模板和数据模型填充。 ### 五、示例代码 ```java import org.jxls...

    Excel报表导出,复杂Excel模板导出(带单元格合并),jxls2

    本项目专注于解决这一问题,通过使用`jxls2`库,能够实现复杂Excel模板的导出,包括单元格的合并,满足多种报表导出需求。现在我们将详细探讨这个项目的核心技术和应用场景。 首先,`jxls2`是一个强大的Java库,它...

    使用xls或xlsx模板(jxls语法)导出Excel并下载的Demo

    而当我们需要在Web应用程序中实现动态生成和导出Excel文件时,一种高效的方法是利用模板和特定的库,如jxls。本文将深入探讨如何使用jxls库,结合xls或xlsx模板,来实现Excel文件的导出和下载。 首先,了解jxls。...

    完整的导出EXCEL(poi/jxls)

    总的来说,Apache POI和jxls是Java开发中导出Excel的强大工具,它们可以帮助我们轻松地处理各种复杂的Excel导出需求,无论是简单的数据列表还是复杂的报表模板。通过熟练掌握这两个库,你可以为用户提供高效、灵活的...

    使用jxls标签导出Excel说明

    使用jxls标签导出Excel说明 基于jxls标签导出Excel的方式可以简化Excel报表的生成过程,并且可以实现复杂的报表功能。jxls标签可以直接写在Excel模板中,并可以与POI结合使用,生成复杂的Excel报表。 JXLS是一个...

    jxls导出模板

    jxls是一个基于Java的库,它允许开发者使用Apache POI库来扩展XLS(X)模板,从而动态生成Excel文件。 jxls的核心概念是通过模板和Java对象之间的映射关系,将业务数据填充到预定义的Excel模板中。这种方式使得开发者...

    用Jxls实现数据导入excel实例

    Jxls是一个强大的库,它简化了Java应用程序与Excel工作簿之间的交互,使我们能够方便地进行数据导入和导出。本文将详细介绍如何使用Jxls实现数据导入Excel的实例。 Jxls库的核心功能在于提供了一种声明式的方式来...

    jxls-core-1.1.3.jar ,java根据模版导出excel功能

    此版本是自己编译的,增加了实现java 在excel模版上导出图片的功能,并优化了模版导出数据功能

    jxls生成并导出excel所需jar包

    `jxls`是一个非常实用的库,它允许开发者使用JSP标签和Java编程方式来处理Excel模板,从而方便地生成和导出Excel文件。本篇文章将详细解释`jxls`库以及与其相关的`jar`包,包括`commons-jexl`,并讨论如何在项目中...

    JXLS 2.4.0 excel 导出 可以运行在 JDK 1.6

    在进行导出时,JXLS 2.4.0的“直接运行”功能意味着使用者无需进行复杂的配置或设置,只需提供必要的数据和模板,就可以快速生成Excel文件。这简化了开发流程,提高了工作效率。 压缩包中的文件“JexcelTemple”...

    jxls模板导出Excel所需jar包

    jxls是一个强大的库,它允许开发者使用模板的方式来导出Excel数据,极大地提高了工作效率。本篇将详细介绍jxls库及其在模板导出Excel中的应用。 首先,我们要了解什么是jxls。jxls是一个Java库,它扩展了Apache POI...

    jxls-导入导出-java

    `jxls`扩展了POI的功能,使得我们可以使用类似于JSP的语法来定义Excel模板,然后通过Java代码动态填充这些模板,生成复杂的Excel表格。 在"jxls例子"中,我们可以看到如何利用`jxls`进行实际操作。首先,你需要创建...

    SpringBoot快速集成jxls-poi(自定义模板,支持本地文件导出,在线文件导出)

    这种方式大大简化了使用POI库直接操作Excel的复杂性,同时也提供了更好的可维护性和可扩展性。jxls提供了一种声明式的方式来处理Excel模板,使得开发者可以专注于数据和业务逻辑,而不是繁琐的表格格式设置。在实际...

Global site tag (gtag.js) - Google Analytics