通過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數據的情況下,兩者大小沒有太大差距。