通过xml方式导出excel没有65536数据条数限制,于是尝试了一下,具体代码如下:
private static int maxRow = 1000000;
/**
* 通过xml方式写入文档导出excel文件
* @param sheetName
* @param sheetData
* @return
* @throws Exception
*/
public static StringBuffer exportExcel(String sheetName,ExcelSheetData sheetData) throws Exception{
// 创建一个excel应用文件
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
sb.append("\n");
sb.append("<?mso-application progid=\"Excel.Sheet\"?>");
sb.append("\n");
sb.append("<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"");
sb.append("\n");
sb.append(" xmlns:o=\"urn:schemas-microsoft-com:office:office\"");
sb.append("\n");
sb.append(" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"");
sb.append("\n");
sb.append(" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"");
sb.append("\n");
sb.append(" xmlns:html=\"http://www.w3.org/TR/REC-html40\">");
sb.append("\n");
try {
int headersLength = sheetData.getTitleList().size();
sb.append("<Worksheet ss:Name=\"" + sheetName + "\">");
// sb.append("\n");
sb.append("<Table ss:ExpandedColumnCount=\"" + headersLength
+ "\" ss:ExpandedRowCount=\""+maxRow+"\" x:FullColumns=\"1\" x:FullRows=\"1\">");
// sb.append("\n");
sb.append("<Row>");
//标题
for(int i=0;i<sheetData.getTitleList().size();i++){
sb.append("<Cell><Data ss:Type=\"String\">"+sheetData.getTitleList().get(i).getName()+"</Data></Cell>");
// sb.append("\n");
}
sb.append("</Row>");
// sb.append("\n");
//导入数据
for(int i=0;i<sheetData.getDataMapList().size();i++){
sb.append("<Row>");
for (Map.Entry<Integer,Object> dataMap : sheetData.getDataMapList().get(i).entrySet()) {
sb.append("<Cell><Data ss:Type=\"String\">"+dataMap.getValue()+"</Data></Cell>");
// sb.append("\n");
}
sb.append("</Row>");
// sb.append("\n");
}
sb.append("</Table>");
sb.append("<WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">");
sb.append("\n");
sb.append("<ProtectObjects>False</ProtectObjects>");
sb.append("\n");
sb.append("<ProtectScenarios>False</ProtectScenarios>");
sb.append("\n");
sb.append("</WorksheetOptions>");
sb.append("\n");
sb.append("</Worksheet>");
sb.append("</Workbook>");
sb.append("\n");
} catch (Exception e) {
e.printStackTrace();
}
return sb;
}
测试方法如下:
public static void main(String[] args) throws Exception {
String filename = "test";
List<ExcelTitleData> titleList = new ArrayList<ExcelTitleData>();
titleList.add(new ExcelTitleData("编号",10));
titleList.add(new ExcelTitleData("账号",20));
titleList.add(new ExcelTitleData("密码",30));
titleList.add(new ExcelTitleData("交易码",10));
String sheetName ="用户信息";
List<Map<Integer, Object>> dataList = new ArrayList<Map<Integer, Object>>();
Map<Integer, Object> map = new HashMap<Integer, Object>();
map.put(1,222);
map.put(2,"wdwd");
map.put(3,789);
map.put(4,"Dqwqwe");
for (int i = 0; i < 10 ; i++) {
dataList.add(map);
}
ExcelSheetData sheetData = new ExcelSheetData(sheetName,titleList,dataList);
StringBuffer sb = exportExcel(filename,sheetData);
long start = System.currentTimeMillis();
outputLocalXls(sb,filename,"E://1/");
long end = System.currentTimeMillis();
System.out.println(end-start);
}
public static void outputLocalXls(StringBuffer sb, String fileName, String path) {
try {
FileOutputStream fos = null;
try {
File f = new File(path+fileName +".xls");
if (!f.getParentFile().exists()) { //判断父目录路径是否存在,即test.txt前的I:\a\b\
try {
f.getParentFile().mkdirs(); //不存在则创建父目录
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
fos = new FileOutputStream(path+fileName +".xls");
fos.write(sb.toString().getBytes());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos!=null) {
fos.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
下面是程序运行对照
20W条数据导出情况下
xml方式 | jxl方式 | |
平均耗时 | 420MS左右 | 3600ms左右 |
文件大小 | 39,800,898 字节 | 21,436,416 字节 |
100条数据导出情况下
xml方式 | jxl方式 | |
平均耗时 | 6ms左右 | 300ms左右 |
文件大小 | 20,798 字节 | 22,528 字节 |
这里可以明显看出,运行效率上,xml方式有明显的优势。
而数据量较小时,两种方式的文件大小上,并没有多少差距,数据量大时,jxl导出的文件要小许多。
猜测是因为jxl导出的excel内容压缩过,无法使用文本方式进行查看。
验证方式:将jxl导出excel转存为xml,与xml导出的ecxel转存为xml文件进行比较发现、20W数据的情况下,两者大小没有太大差距。