我正在尝试使用Apache Poi将ResultSet写入Excel(* .xlsx)表.
Office Excel中的表对象错误无效
但是,即使它写入Excel文件没有任何错误,当我尝试在Office Excel 2013中打开它时,它会显示错误并删除表对象以仅提供纯数据视图.
public static void writeExcel(ResultSet rs,int sqliteRowCount,String dir) { System.out.println("Writing Excel(*.xlsx) File..."); XSSFWorkbook workbook = null; try { if (rs != null) { // Get ResultSet MetaData ResultSetMetaData rsmd = rs.getMetaData(); // Number of columns int numColumns = rsmd.getColumnCount(); // Number of rows // + 1 for headers int numRows = sqliteRowCount + 1; workbook = new XSSFWorkbook(); // Create Excel Table XSSFSheet sheet = workbook.createSheet("Text"); XSSFTable table = sheet.createTable(); table.setDisplayName("Test"); CTTable cttable; cttable = table.getCTTable(); // Style configurations CTTableStyleInfo style = cttable.addNewTableStyleInfo(); style.setName("TableStyleMedium16"); style.setShowColumnStripes(false); style.setShowRowStripes(true); // Set Table Span Area AreaReference reference = new AreaReference(new CellReference(0,0),new CellReference(numRows - 1,numColumns - 1)); cttable.setRef(reference.formatAsString()); cttable.setId(1); cttable.setName("Test"); cttable.setDisplayName("Test"); cttable.setTotalsRowCount(numRows); cttable.setTotalsRowShown(false); // Create Columns CTTableColumns columns = cttable.addNewTableColumns(); columns.setCount(numColumns); // Create Column,Row,Cell Objects CTTableColumn column; XSSFRow row; // Add Header and Columns XSSFRow headerRow = sheet.createRow(0); for (int i = 0; i < numColumns; i++) { column = columns.addNewTableColumn(); column.setName("Column" + (i + 1)); column.setId(i + 1); headerRow.createCell(i).setCellValue(rsmd.getColumnLabel(i + 1)); } // Write each row from ResultSet int rowNumber = 1; while (rs.next()) { row = sheet.createRow(rowNumber); for (int y = 0; y < numColumns; y++) { row.createCell(y).setCellValue(rs.getString(y + 1)); } rowNumber++; } // Set AutoFilter CTAutoFilter fltr = CTAutoFilter.Factory.newInstance(); fltr.setRef((new AreaReference(new CellReference(0,numColumns - 1))).formatAsString()); cttable.setAutoFilter(fltr); // sheet.setAutoFilter(CellRangeAddress.valueOf((new AreaReference(new CellReference(0,numColumns - 1))).formatAsString())); // Freeze Pan sheet.createFreezePane(0,1,2); } } catch (sqlException ex) { System.out.println("sql Error while writing Excel file!"); } finally { try { // Let's write the excel file now if (workbook != null) { String excelDir = dir + File.separator + "workbook.xlsx"; try (final FileOutputStream out = new FileOutputStream(excelDir)) { workbook.write(out); } } } catch (IOException ex) { System.out.println("IO Error while writing Excel summary file!"); } } }
我知道我的代码有问题,但无法弄明白.
任何想法,为什么会发生这种情况,我的代码中可能存在错误.
更新1:
如果使用Apache POI创建,则在Excel存档中使用表格XML文件
<?xml version="1.0" encoding="UTF-8"?> <table displayName="Test" ref="A1:B881" id="1" name="Test" totalsRowCount="881" xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" totalsRowShown="0"><autoFilter ref="A1:B881"/><tableColumns count="2"><tableColumn name="ID" id="1"/><tableColumn name="Name" id="2"/><tableStyleInfo name="TableStyleMedium2" showColumnStripes="true" showRowStripes="true"/></table>
如果手动创建表,则在Excel归档中使用表格XML文件
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" id="1" name="Table1" displayName="Table1" ref="A1:B881" totalsRowShown="0"><autoFilter ref="A1:B881"/><tableColumns count="2"><tableColumn id="1" name="ID"/><tableColumn id="2" name="Name"/></tableColumns><tableStyleInfo name="TableStyleLight9" showFirstColumn="0" showLastColumn="0" showRowStripes="1" showColumnStripes="0"/></table>
此外,如果我打开Excel存档,它在Apache POI创建的主题文件夹中没有主题文件夹,但它存在于Office Excel中手动创建的主题文件夹中.奇怪.
更新2:
示例可执行代码(使用Netbeans):
/* * To change this license header,choose License Headers in Project Properties. * To change this template file,choose Tools | Templates * and open the template in the editor. */ package apachepoi_exceltest; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellReference; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFTable; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumns; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyleInfo; /** * */ public class ApachePOI_ExcelTest { /** * @param args the command line arguments */ public static void main(String[] args) { String outputDir = "Your Local Directory Here"; // TODO code application logic here HashMap<String,String> dataMap = new HashMap<>(); dataMap.put("ID 1","Dummy Name 1"); dataMap.put("ID 2","Dummy Name 2"); dataMap.put("ID 3","Dummy Name 3"); dataMap.put("ID 4","Dummy Name 4"); writeExcel(dataMap,outputDir); } private static void writeExcel(HashMap<String,String> dataMap,String outputDir) { System.out.println("Writing Excel(*.xlsx) Summary File..."); XSSFWorkbook workbook = null; try { // Number of columns int numColumns = 2; // ID and Name // Number of rows int numRows = dataMap.size() + 1; // +1 for header // Create Workbook workbook = new XSSFWorkbook(); // Create Excel Table XSSFSheet sheet = workbook.createSheet("Summary"); XSSFTable table = sheet.createTable(); table.setDisplayName("Test"); CTTable cttable; cttable = table.getCTTable(); // Style configurations CTTableStyleInfo style = cttable.addNewTableStyleInfo(); style.setName("TableStyleMedium16"); style.setShowColumnStripes(false); style.setShowRowStripes(true); // Set Tabel Span Area AreaReference reference = new AreaReference(new CellReference(0,numColumns - 1)); cttable.setRef(reference.formatAsString()); cttable.setId(1); cttable.setName("Test"); cttable.setDisplayName("Test"); cttable.setTotalsRowCount(numRows); cttable.setTotalsRowShown(false); // Create Columns CTTableColumns columns = cttable.addNewTableColumns(); columns.setCount(numColumns); // Create Column,Cell Objects CTTableColumn column; XSSFRow row; // Add ID Header column = columns.addNewTableColumn(); column.setName("Column" + (1)); column.setId(1); // Add Name Header column = columns.addNewTableColumn(); column.setName("Column" + (1)); column.setId(1); // Add Header Row XSSFRow headerRow = sheet.createRow(0); headerRow.createCell(0).setCellValue("ID"); headerRow.createCell(1).setCellValue("Name"); int rowNumber = 1; for (Map.Entry<String,String> entry : dataMap.entrySet()) { String id = entry.getKey(); String name = entry.getValue(); row = sheet.createRow(rowNumber); row.createCell(0).setCellValue(id); row.createCell(1).setCellValue(name); rowNumber++; } // Set Filter (Below three lines code somehow not working in this example,so setting AutoFilter to WorkSheet) // CTAutoFilter fltr = CTAutoFilter.Factory.newInstance(); // fltr.setRef((new AreaReference(new CellReference(0,numColumns - 1))).formatAsString()); // cttable.setAutoFilter(fltr); sheet.setAutoFilter(CellRangeAddress.valueOf((new AreaReference(new CellReference(0,numColumns - 1))).formatAsString())); // Freeze First Row as header Row sheet.createFreezePane(0,2); } catch (Exception ex) { System.out.println("Error while writing Excel summary file!"); } finally { try { // Lets write the Excel File Now if (workbook != null) { String excelDir = outputDir + File.separator + "workbook.xlsx"; try (final FileOutputStream out = new FileOutputStream(excelDir)) { workbook.write(out); } } } catch (IOException ex) { System.out.println("IO Error while writing Excel summary file!"); } } } }
使用的库:
OOXML-模式-1.1.jar
POI-3.11-beta2-20140822.jar
POI-OOXML-3.11-beta2-20140822.jar
XMLBeans的-2.6.0.jar