【问题标题】:How do I convert an area in an Excel doc to a table using Apache POI?如何使用 Apache POI 将 Excel 文档中的区域转换为表格?
【发布时间】:2020-04-20 17:07:18
【问题描述】:

我编写了一个应用程序,它从数据库中获取数据并使用 Apache POI 库中的 XSSF 类从所述数据创建 Excel 文档。我已经导入了 poi、poi-ooxml 和 poi-ooxml-schemas,都是 4.1.0 版本。

文件写得很好,打开文件时没有错误,直到我取消注释表创建代码,我将在下面粘贴:

CellReference topLeft = new CellReference(sheet.getRow(3).getCell(0));
CellReference bottomRight = new CellReference(sheet.getRow(nextRow-1).getCell(3));
AreaReference tableArea = workbook.getCreationHelper().createAreaReference(topLeft, bottomRight);
XSSFTable dataTable = sheet.createTable(tableArea);

我添加了一些额外的字段只是为了排除一些潜在的问题:

int test = dataTable.getEndRowIndex(); //Returns 968, as expected
tableArea = dataTable.getArea(); //The area remains A4 to D968, as expected
int testColumns = dataTable.getColumnCount(); //Returns 4, as expected
int testRows = dataTable.getRowCount(); //Returns 968, as expected

取消注释上述代码后尝试打开工作簿时,出现以下错误:

“我们发现 'filename.xlsx' 中的某些内容存在问题。您希望我们尽可能多地尝试恢复吗?如果您信任此工作簿的来源,请单击是。”

点击yes后出现数据不存在表格并显示如下错误: “已删除部分:/xl/tables/table1.xml 部分存在 XML 错误。(表)加载错误。第 2 行,第 94 列。”

这很令人困惑,因为所有迹象都表明表格中应该只有 4 列...任何人都知道可能发生了什么以及如何解决它?

【问题讨论】:

    标签: java excel apache-poi xssf


    【解决方案1】:

    您的XSSFTable 缺少名称。至少必须使用XSSFTable.setDisplayName 设置显示名称。

    所以dataTable.setDisplayName("Table1"); 应该可以解决您的问题。

    如何检测?

    首先创建一个简单的完整示例。然后,使用Excel 打开结果后,注意/xl/tables/table1.xml 的哪一行/哪一列出现错误。然后在解压缩*.xlsx 后打开/xl/tables/table1.xml。现在你应该会发现,错误的XML 是:

    <table id="1" ref="A4:D..." xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><tableColumns count="4">
    

    错误紧跟在&lt;table id="1" ref="A4:D..." xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"&gt; 之后。所以第一个标签似乎不完整。

    现在将其与 XML Excel 本身创建的比较。你会发现Exceltable元素总是会设置name="TableN" displayName="TableN"

    完整示例:

    import java.io.FileOutputStream;
    import org.apache.poi.xssf.usermodel.*;
    import org.apache.poi.ss.util.AreaReference;
    import org.apache.poi.ss.util.CellReference;
    
    import java.util.GregorianCalendar;
    
    class CreateExcelTable {
    
     public static void main(String[] args) throws Exception {
    
      Object[][] data = new Object[][] {
       new Object[] {"Text", "Date", "Number", "Boolean"},
       new Object[] {"Text 1", new GregorianCalendar(2020, 0, 1), 1234d, true},
       new Object[] {"Text 2", new GregorianCalendar(2020, 1, 15), 5678d, true},
       new Object[] {"Text 3", new GregorianCalendar(2020, 2, 1), 90.1234, false},
       new Object[] {"Text 4", new GregorianCalendar(2020, 3, 15), 567.89, false}
      };
    
      try (XSSFWorkbook workbook = new XSSFWorkbook();
           FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {
    
       XSSFCellStyle dateCellStyle = workbook.createCellStyle();
       dateCellStyle.setDataFormat(14);
    
       XSSFSheet sheet = workbook.createSheet();
       XSSFRow row = sheet.createRow(0);
       XSSFCell cell = row.createCell(0);
       cell.setCellValue("Lorem ipsum");
       row = sheet.createRow(1);
       cell = row.createCell(0);
       cell.setCellValue("semit dolor");
    
       int nextRow = 3;
       int nextCol = 0;
       for (Object[] dataRow : data) {
        row = sheet.createRow(nextRow++);
        nextCol = 0;
        for (Object value : dataRow) {
         cell = row.createCell(nextCol++);
         if (value instanceof String) cell.setCellValue((String)value);
         else if (value instanceof GregorianCalendar) {
          cell.setCellValue((GregorianCalendar)value);
          cell.setCellStyle(dateCellStyle);
         }
         else if (value instanceof Double) cell.setCellValue((Double)value);
         else if (value instanceof Boolean) cell.setCellValue((Boolean)value);
        }
       }
    
       CellReference topLeft = new CellReference(sheet.getRow(3).getCell(0));
       CellReference bottomRight = new CellReference(sheet.getRow(nextRow-1).getCell(3));
       AreaReference tableArea = workbook.getCreationHelper().createAreaReference(topLeft, bottomRight);
       XSSFTable dataTable = sheet.createTable(tableArea);
       //dataTable.setName("Table1");
       dataTable.setDisplayName("Table1");
    
    /* 
       //this styles the table as Excel would do per default
       dataTable.getCTTable().addNewTableStyleInfo();
       XSSFTableStyleInfo style = (XSSFTableStyleInfo)dataTable.getStyle();
       style.setName("TableStyleMedium2");
       style.setShowColumnStripes(false);
       style.setShowRowStripes(true);
    
       dataTable.getCTTable().addNewAutoFilter().setRef(tableArea.formatAsString());
    */
    
       workbook.write(fileout);
      }
    
     }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-23
      • 2014-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多