SXSSF Excel table
SXSSF with Excel table
我正在尝试在流式工作簿 (SXSSFWorkbook) 中创建 Excel table。 API 不直接支持它,但我通过访问底层 XSSFWorkbook (workbook.getXSSFWorkbook) 取得了一些成功。
当我在 Excel (2007) 中打开文件时,它显示 "Excel found unreadable content in "test.xlsx”。是否要恢复此工作簿的内容?”。单击“是”成功修复了工作簿,我得到了正确的结果。
日志显示 "Repaired Records: Table from /xl/tables/table1.xml part (Table)"。
有人知道如何避免 Excel 错误吗?
下面是一个例子:
public class SXSSFTest {
private static final int NB_ROWS = 5;
private static final int NB_COLS = 5;
public static void main(String[] args) throws Exception {
try (SXSSFWorkbook workbook = new SXSSFWorkbook();
FileOutputStream outputStream = new FileOutputStream("C:\test.xlsx")) {
SXSSFSheet sheet = workbook.createSheet();
fillSheet(sheet);
String dataRange = new AreaReference(
new CellReference(0, 0),
new CellReference(NB_ROWS - 1, NB_COLS - 1))
.formatAsString();
CTTable cttable = workbook.getXSSFWorkbook()
.getSheetAt(0)
.createTable()
.getCTTable();
CTTableStyleInfo tableStyle = cttable.addNewTableStyleInfo();
tableStyle.setName("TableStyleMedium17");
cttable.setRef(dataRange);
cttable.setDisplayName("TABLE");
cttable.setName("TABLE");
cttable.setId(1L);
CTTableColumns columns = cttable.addNewTableColumns();
columns.setCount(NB_COLS);
for (int c = 0; c < NB_COLS; c++) {
CTTableColumn column = columns.addNewTableColumn();
column.setName("Column" + c);
column.setId(c + 1L);
}
cttable.setAutoFilter(CTAutoFilter.Factory.newInstance());
workbook.write(outputStream);
}
}
private static void fillSheet(SXSSFSheet sheet) {
for (int rowNb = 0; rowNb < NB_ROWS; rowNb++) {
SXSSFRow row = sheet.createRow(rowNb);
for (int colNb = 0; colNb < NB_COLS; colNb++) {
SXSSFCell cell = row.createCell(colNb);
cell.setCellValue("Cell-" + colNb);
}
}
}
}
table 第一行的单元格值必须与列名对应。
您在 main
方法中的代码将列命名为 Column0
... Column4
但您在 fillSheet
方法中的代码写入 "Cell-0" ... "Cell-4" 到第一行的单元格中。这不匹配。
您可以像这样更改 fillSheet
方法:
...
private static void fillSheet(SXSSFSheet sheet) {
for (int rowNb = 0; rowNb < NB_ROWS; rowNb++) {
SXSSFRow row = sheet.createRow(rowNb);
for (int colNb = 0; colNb < NB_COLS; colNb++) {
SXSSFCell cell = row.createCell(colNb);
if (rowNb==0) cell.setCellValue("Column" + colNb); //first row are column names
else cell.setCellValue("Cell-" + colNb);
}
}
}
...
这是一个更新版本,修复了一些已弃用方法的用法(使用 POI 4.1.2 测试)。请注意,它不再需要手动创建列和设置 ID,一切都由 createTable(dataRange)
:
完成
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
import java.io.FileOutputStream;
public class SXSSFTest {
private static final int NB_ROWS = 5;
private static final int NB_COLS = 5;
public static void main(String[] args) throws Exception {
try (SXSSFWorkbook workbook = new SXSSFWorkbook();
FileOutputStream outputStream = new FileOutputStream("C:\test.xlsx")) {
SXSSFSheet sheet = workbook.createSheet();
fillSheet(sheet);
AreaReference dataRange = new AreaReference(
new CellReference(0, 0),
new CellReference(NB_ROWS - 1, NB_COLS - 1),
SpreadsheetVersion.EXCEL2007
);
CTTable cttable = workbook.getXSSFWorkbook()
.getSheetAt(0)
.createTable(dataRange)
.getCTTable();
CTTableStyleInfo tableStyle = cttable.addNewTableStyleInfo();
tableStyle.setName("TableStyleMedium17");
cttable.setDisplayName("TABLE");
cttable.setName("TABLE");
CTTableColumns columns = cttable.getTableColumns();
for (int c = 0; c < NB_COLS; c++) {
CTTableColumn column = columns.getTableColumnArray(c);
column.setName("Column title " + c);
}
cttable.setAutoFilter(CTAutoFilter.Factory.newInstance());
workbook.write(outputStream);
}
}
private static void fillSheet(SXSSFSheet sheet) {
for (int rowNb = 0; rowNb < NB_ROWS; rowNb++) {
SXSSFRow row = sheet.createRow(rowNb);
for (int colNb = 0; colNb < NB_COLS; colNb++) {
SXSSFCell cell = row.createCell(colNb);
if (rowNb == 0) {
cell.setCellValue("Column title " + colNb); //first row are column names
} else {
cell.setCellValue("Cell-" + colNb);
}
}
}
}
}
我正在尝试在流式工作簿 (SXSSFWorkbook) 中创建 Excel table。 API 不直接支持它,但我通过访问底层 XSSFWorkbook (workbook.getXSSFWorkbook) 取得了一些成功。
当我在 Excel (2007) 中打开文件时,它显示 "Excel found unreadable content in "test.xlsx”。是否要恢复此工作簿的内容?”。单击“是”成功修复了工作簿,我得到了正确的结果。
日志显示 "Repaired Records: Table from /xl/tables/table1.xml part (Table)"。
有人知道如何避免 Excel 错误吗?
下面是一个例子:
public class SXSSFTest {
private static final int NB_ROWS = 5;
private static final int NB_COLS = 5;
public static void main(String[] args) throws Exception {
try (SXSSFWorkbook workbook = new SXSSFWorkbook();
FileOutputStream outputStream = new FileOutputStream("C:\test.xlsx")) {
SXSSFSheet sheet = workbook.createSheet();
fillSheet(sheet);
String dataRange = new AreaReference(
new CellReference(0, 0),
new CellReference(NB_ROWS - 1, NB_COLS - 1))
.formatAsString();
CTTable cttable = workbook.getXSSFWorkbook()
.getSheetAt(0)
.createTable()
.getCTTable();
CTTableStyleInfo tableStyle = cttable.addNewTableStyleInfo();
tableStyle.setName("TableStyleMedium17");
cttable.setRef(dataRange);
cttable.setDisplayName("TABLE");
cttable.setName("TABLE");
cttable.setId(1L);
CTTableColumns columns = cttable.addNewTableColumns();
columns.setCount(NB_COLS);
for (int c = 0; c < NB_COLS; c++) {
CTTableColumn column = columns.addNewTableColumn();
column.setName("Column" + c);
column.setId(c + 1L);
}
cttable.setAutoFilter(CTAutoFilter.Factory.newInstance());
workbook.write(outputStream);
}
}
private static void fillSheet(SXSSFSheet sheet) {
for (int rowNb = 0; rowNb < NB_ROWS; rowNb++) {
SXSSFRow row = sheet.createRow(rowNb);
for (int colNb = 0; colNb < NB_COLS; colNb++) {
SXSSFCell cell = row.createCell(colNb);
cell.setCellValue("Cell-" + colNb);
}
}
}
}
table 第一行的单元格值必须与列名对应。
您在 main
方法中的代码将列命名为 Column0
... Column4
但您在 fillSheet
方法中的代码写入 "Cell-0" ... "Cell-4" 到第一行的单元格中。这不匹配。
您可以像这样更改 fillSheet
方法:
...
private static void fillSheet(SXSSFSheet sheet) {
for (int rowNb = 0; rowNb < NB_ROWS; rowNb++) {
SXSSFRow row = sheet.createRow(rowNb);
for (int colNb = 0; colNb < NB_COLS; colNb++) {
SXSSFCell cell = row.createCell(colNb);
if (rowNb==0) cell.setCellValue("Column" + colNb); //first row are column names
else cell.setCellValue("Cell-" + colNb);
}
}
}
...
这是一个更新版本,修复了一些已弃用方法的用法(使用 POI 4.1.2 测试)。请注意,它不再需要手动创建列和设置 ID,一切都由 createTable(dataRange)
:
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
import java.io.FileOutputStream;
public class SXSSFTest {
private static final int NB_ROWS = 5;
private static final int NB_COLS = 5;
public static void main(String[] args) throws Exception {
try (SXSSFWorkbook workbook = new SXSSFWorkbook();
FileOutputStream outputStream = new FileOutputStream("C:\test.xlsx")) {
SXSSFSheet sheet = workbook.createSheet();
fillSheet(sheet);
AreaReference dataRange = new AreaReference(
new CellReference(0, 0),
new CellReference(NB_ROWS - 1, NB_COLS - 1),
SpreadsheetVersion.EXCEL2007
);
CTTable cttable = workbook.getXSSFWorkbook()
.getSheetAt(0)
.createTable(dataRange)
.getCTTable();
CTTableStyleInfo tableStyle = cttable.addNewTableStyleInfo();
tableStyle.setName("TableStyleMedium17");
cttable.setDisplayName("TABLE");
cttable.setName("TABLE");
CTTableColumns columns = cttable.getTableColumns();
for (int c = 0; c < NB_COLS; c++) {
CTTableColumn column = columns.getTableColumnArray(c);
column.setName("Column title " + c);
}
cttable.setAutoFilter(CTAutoFilter.Factory.newInstance());
workbook.write(outputStream);
}
}
private static void fillSheet(SXSSFSheet sheet) {
for (int rowNb = 0; rowNb < NB_ROWS; rowNb++) {
SXSSFRow row = sheet.createRow(rowNb);
for (int colNb = 0; colNb < NB_COLS; colNb++) {
SXSSFCell cell = row.createCell(colNb);
if (rowNb == 0) {
cell.setCellValue("Column title " + colNb); //first row are column names
} else {
cell.setCellValue("Cell-" + colNb);
}
}
}
}
}