Java – convert resultset to excel (*. Xlsx) table using Apache poi
I'm trying to write the resultset to an excel (*. Xlsx) table using Apache poi
Table object error in Office Excel invalid
However, even if it is written to an excel file without any errors, when I try to open it in Office Excel 2013, it will display errors and delete the table object to provide only a pure data view
This is a rough example code using this example:
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!"); } } }
I know there is something wrong with my code, but I can't figure it out Any idea why this happens, there may be an error in my code
Update 1:
If you create using Apache POI, use the table XML file in the excel archive
<?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>
If you create a table manually, use the table XML file in the excel archive
<?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>
In addition, if I open the excel archive, it does not have a theme folder in the theme folder created by Apache POI, but it exists in the theme folder manually created in Office Excel Strange
Update 2: sample executable code (using 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!"); } } } }
Libraries used:
OOXML schema-1.1 jar
POI-3.11-beta2-20140822. jar
POI-OOXML-3.11-beta2-20140822. jar
Xmlbeans - 2.6 0.jar
Solution
What's wrong with your code is that there is a line "Cttable.settotalsrowcount (NumRows);" Delete it and everything will work If in doubt, compare the XML definitions of some worksheets created manually in Excel with those created using Apache poi