用JXLS和poi导出Excel

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
 
 
public class VM {
	
	private String id;
	private String name;
	private String scale;
	private Date created;
	private Double price;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getScale() {
		return scale;
	}
	public void setScale(String scale) {
		this.scale = scale;
	}
	public Date getCreated() {
		return created;
	}
	public void setCreated(Date created) {
		this.created = created;
	}
	public Double getPrice() {
		return price;
	}
	public void setPrice(Double price) {
		this.price = price;
	}
	
	

}


 

 
Java代码 复制代码  收藏代码
  1. String srcFilePath = "E:\\tmp\\template-simple.xlsx";  
  2. Map<String, Object> beanParams = new HashMap<String, Object>();  
  3. List<VM> vms = new ArrayList<VM>();  
  4. VM vm = new VM();  
  5. vm.setName("我的CENTOS");  
  6. vm.setPrice(103);  
  7. vm.setScale("2CPU, 2G MEM, 2T DISK");  
  8. vm.setCreated(new Date());  
  9. vms.add(vm);  
  10. VM vm2 = new VM();  
  11. vm2.setName("my-ubuntu");  
  12. vm2.setPrice(200);  
  13. vm2.setScale("1CPU, 3G MEM, 1T DISK");  
  14. vm2.setCreated(new Date());  
  15. vms.add(vm2);  
  16. beanParams.put("vms", vms);  
  17.   
  18. String destFilePath = "E:\\tmp\\simple.xlsx";  
  19.   
  20. XLSTransformer transformer = new XLSTransformer();  
  21. transformer.transformXLS(srcFilePath, beanParams, destFilePath);  
        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方法:

Java代码 复制代码  收藏代码
  1. package org.jamee.demo.poiexcel;  
  2.   
  3. import java.io.FileInputStream;  
  4. import java.io.FileOutputStream;  
  5. import java.io.InputStream;  
  6. import java.io.OutputStream;  
  7. import java.util.ArrayList;  
  8. import java.util.HashMap;  
  9. import java.util.List;  
  10. import java.util.Map;  
  11.   
  12. import net.sf.jxls.transformer.XLSTransformer;  
  13.   
  14. import org.apache.poi.ss.usermodel.Workbook;  
  15.   
  16. public class ExcelUtil {  
  17.     private static final String DEFAULT_SHEET_NAME = "sheet";  
  18.   
  19.     /** 
  20.      * 导出无动态表头的Excel文件 
  21.      * <p> 
  22.      * 参考重载的有动态表头注释 
  23.      * </p> 
  24.      * @param destOutputStream 
  25.      * @param templateInputStream 
  26.      * @param data 
  27.      * @param dataKey 
  28.      * @param maxRowPerSheet 
  29.      * @throws Exception 
  30.      */  
  31.     @SuppressWarnings("rawtypes")  
  32.     public static void generateExcelByTemplate(OutputStream destOutputStream,   
  33.             InputStream templateInputStream,   
  34.             List data, String dataKey,  
  35.             int maxRowPerSheet) throws Exception {  
  36.         generateExcelByTemplate(destOutputStream,  
  37.                 templateInputStream,  
  38.                 nullnull,  
  39.                 data, dataKey,  
  40.                 maxRowPerSheet);  
  41.     }  
  42.   
  43.     /** 
  44.      * 通过Excel模版生成Excel文件 
  45.      * <p> 
  46.      * 创建Excel模版,变量类似JSP tag风格。 
  47.      * 例如: 
  48.      * <ul> 
  49.      * <li>无动态表头 
  50.      * <pre> 
  51.      * 序号   名称  规格  创建时间    价格 
  52.      * &lt;jx:forEach items="${vms}" var="vm"&gt; 
  53.      * ${vm.id} ${vm.name} ${vm.scale} ${vm.created} ${vm.price} 
  54.      * &lt;/jx:forEach&gt; 
  55.      * </pre> 
  56.      * </li> 
  57.      * <li>有动态表头 
  58.      * <pre> 
  59.      * 项目/数量/时间    &lt;jx:forEach items="${dates}" var="date"&gt;    ${date} &lt;/jx:forEach&gt; 
  60.      * &lt;jx:forEach items="${itemsx}" var="item"&gt;             
  61.      * ${item.name}    &lt;jx:forEach items="${item.counts}" var="count"&gt; ${count}    &lt;/jx:forEach&gt; 
  62.      * &lt;/jx:forEach&gt;            
  63.      * </pre> 
  64.      * </li> 
  65.      * </ul> 
  66.      * 调用该方法则生成对应的Excel文件。 
  67.      * </p> 
  68.      * <p> 
  69.      * 注意:dataKey不能是items, items是保留字,如果用items则会提示:Collection is null并抛出NullPointerException 
  70.      * </p> 
  71.      * @param destOutputStream Excel输出流 
  72.      * @param templateInputStream Excel模版输入流 
  73.      * @param header 动态表头 
  74.      * @param headerKey 表头的变量 
  75.      * @param data 数据项 
  76.      * @param dataKey 数据项变量 
  77.      * @param maxRowPerSheet 每个sheet最多行数 
  78.      * @throws Exception 
  79.      */  
  80.     @SuppressWarnings("rawtypes")  
  81.     public static void generateExcelByTemplate(OutputStream destOutputStream,   
  82.             InputStream templateInputStream,   
  83.             List header, String headerKey,  
  84.             List data, String dataKey,  
  85.             int maxRowPerSheet) throws Exception {  
  86.   
  87.         List<List> splitData = null;  
  88.         @SuppressWarnings("unchecked")  
  89.         Map<String, List> beanMap = new HashMap();  
  90.         List<String> sheetNames = new ArrayList<String>();  
  91.         if (data.size() > maxRowPerSheet) {  
  92.             splitData = splitList(data, maxRowPerSheet);  
  93.             sheetNames = new ArrayList<String>(splitData.size());  
  94.             for (int i = 0; i < splitData.size(); ++i) {  
  95.                 sheetNames.add(DEFAULT_SHEET_NAME  + i);  
  96.             }  
  97.         } else {  
  98.             splitData = new ArrayList<List>();  
  99.             sheetNames.add(DEFAULT_SHEET_NAME + 0);  
  100.             splitData.add(data);  
  101.         }  
  102.         if (null != header) {  
  103.             beanMap.put(headerKey, header);  
  104.         }  
  105.         XLSTransformer transformer = new XLSTransformer();  
  106.         Workbook workbook = transformer.transformMultipleSheetsList(  
  107.                 templateInputStream, splitData, sheetNames, dataKey, beanMap, 0);  
  108.         workbook.write(destOutputStream);  
  109.     }  
  110.   
  111.   
  112.     /** 
  113.      * 导出无动态表头的Excel文件,目标文件和模版文件均为文件路径 
  114.      * <p> 
  115.      * 参考重载的有动态表头注释 
  116.      * </p> 
  117.      * @param destFilePath 
  118.      * @param templateFilePath 
  119.      * @param data 
  120.      * @param dataKey 
  121.      * @param maxRowPerSheet 
  122.      * @throws Exception 
  123.      */  
  124.     @SuppressWarnings("rawtypes")  
  125.     public static void generateExcelByTemplate(String destFilePath,   
  126.             String templateFilePath,   
  127.             List data, String dataKey, int maxRowPerSheet) throws Exception {  
  128.         generateExcelByTemplate(destFilePath, templateFilePath, nullnull, data, dataKey, maxRowPerSheet);  
  129.     }  
  130.   
  131.     /** 
  132.      * 导出有动态表头的Excel文件,目标文件和模版文件均为文件路径 
  133.      * <p> 
  134.      * 参考重载的有动态表头注释 
  135.      * </p> 
  136.      * @param destFilePath 
  137.      * @param templateFilePath 
  138.      * @param header 
  139.      * @param headerKey 
  140.      * @param data 
  141.      * @param dataKey 
  142.      * @param maxRowPerSheet 
  143.      * @throws Exception 
  144.      */  
  145.     @SuppressWarnings("rawtypes")  
  146.     public static void generateExcelByTemplate(String destFilePath,   
  147.             String templateFilePath,   
  148.             List header, String headerKey,  
  149.             List data, String dataKey, int maxRowPerSheet) throws Exception {  
  150.         generateExcelByTemplate(new FileOutputStream(destFilePath),  
  151.                 new FileInputStream(templateFilePath),  
  152.                 header, headerKey,  
  153.                 data, dataKey, maxRowPerSheet);  
  154.     }  
  155.   
  156.     @SuppressWarnings({ "rawtypes""unchecked" })  
  157.     private static List<List> splitList(List data, int maxRowPerSheet) {  
  158.         List<List> splitData = new ArrayList<List>();  
  159.         List sdata = null;  
  160.         for (int i = 0; i < data.size(); ++i) {  
  161.             if (0 == i % maxRowPerSheet) {  
  162.                 if (null != sdata) {  
  163.                     splitData.add(sdata);  
  164.                 }  
  165.                 sdata = new ArrayList(maxRowPerSheet);  
  166.             }  
  167.             sdata.add(data.get(i));  
  168.         }  
  169.         if (0 != maxRowPerSheet % data.size()) {  
  170.             splitData.add(sdata);  
  171.         }  
  172.   
  173.         return splitData;  
  174.     }  
  175. }  
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;
    }
}

 

简单用法:

Java代码 复制代码  收藏代码
  1.         List<VM> vms = new ArrayList<VM>();  
  2.         for (int i = 0; i < 21; ++i) {  
  3.             VM vma = new VM();  
  4.             vma.setId(i);  
  5.             vma.setName("我的CENTOS" + i);  
  6.             vma.setPrice(103);  
  7.             vma.setScale("2CPU, 2G MEM, 2T DISK");  
  8.             vma.setCreated(new Date());  
  9.             vms.add(vma);  
  10.         }   
  11. ExcelUtil.generateExcelByTemplate("E:\\tmp\\ex-sample.xlsx""E:\\tmp\\template-simple.xlsx", vms, "vms"10);  
        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生成。

 

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

例如下面这个模版:



 调用示例:

Java代码 复制代码  收藏代码
  1.  List<String> dates = new ArrayList<String>();  
  2. int maxDates = 8;  
  3. for (int i = 0; i < maxDates ; ++i) {  
  4.     dates.add("2013-08-1" + i);  
  5. }  
  6. List<ItemCount> itemCounts = new ArrayList<ItemCount>();  
  7. for (int i = 0; i < 82; ++i) {  
  8.     ItemCount ic = new ItemCount();  
  9.     List<Integer> counts = new ArrayList<Integer>();  
  10.     for (int j = 0; j < maxDates; ++j) {  
  11.         counts.add(j);  
  12.     }  
  13.     ic.setCounts(counts);  
  14.     ic.setName("item" + i);  
  15.     itemCounts.add(ic);  
  16. }  
  17. ExcelUtil.generateExcelByTemplate("E:\\tmp\\ex-cpx.xlsx",   
  18.         "E:\\tmp\\template-matrix.xlsx", dates, "dates", itemCounts, "itemsx"12);  
         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);

 结果:



 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值