将 Jtable 转换为 excel,更新文件错误
Converting Jtable to excel,updated file error
我写了一个代码来创建 jTable 并导出到 Excel.I works.But 当我打开 Excel 文件时文件没有完全恢复。
它显示了以下问题:
已修复部分:/xl/worksheets/sheet2.xml 部分有 XML 错误。加载错误。第 2 行,第 0 列。
已修复部分:/xl/worksheets/sheet7.xml 部分有 XML 错误。加载错误。第 2 行,第 0 列。
删除的记录:/xl/workbook.xml 部分的命名范围(工作簿)
删除的记录:Table 来自 /xl/tables/table1.xml 部分 (Table)
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.awt.event.ActionEvent;
public class GUI {
private static JTextField textField;
private static JTextField textField_1;
public static void main(String args[]) throws IOException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Object rowData[][] = null ;
Object columnNames[] = { "Column One", "Column Two"};
DefaultTableModel model = new DefaultTableModel(rowData,columnNames);
frame.getContentPane().setLayout(null);
JTable table = new JTable(model);
table.setModel(model);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBounds(76, 106, 300, 200);
scrollPane.setVisible(true);
frame.getContentPane().add(scrollPane);
textField = new JTextField();
textField.setBounds(76, 21, 86, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
textField_1 = new JTextField();
textField_1.setBounds(76, 61, 86, 20);
frame.getContentPane().add(textField_1);
textField_1.setColumns(10);
JLabel lblNewLabel = new JLabel("Name");
lblNewLabel.setBounds(20, 24, 46, 14);
frame.getContentPane().add(lblNewLabel);
JLabel lblAge = new JLabel("Age");
lblAge.setBounds(20, 64, 46, 14);
frame.getContentPane().add(lblAge);
JButton btnNewButton = new JButton("Get Data");
btnNewButton.setBounds(235, 40, 89, 23);
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String name = textField.getText().toString();
int age = Integer.parseInt(textField_1.getText());
model.addRow(new Object[] {name,age});
Object obj1 = GetData(table, 0,0 );
System.out.println("Cell value of 1 column and 1 row :" + obj1);
Object obj2 = GetData(table, 0,1 );
System.out.println("Cell value of 2 column and 1 row :" + obj2);
}
});
frame.getContentPane().add(btnNewButton);
JButton btnNewButton_1 = new JButton("Excel");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
try {
writeToExcel(table);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
btnNewButton_1.setBounds(340, 40, 89, 23);
frame.getContentPane().add(btnNewButton_1);
frame.setSize(455, 356);
frame.setVisible(true);
}
protected static void writeToExcel(JTable table) throws Exception {
try {
File file = new File("IET.xlsx");
FileInputStream inputStream = new FileInputStream(file);
XSSFWorkbook workbook = (XSSFWorkbook) WorkbookFactory.create(inputStream);
XSSFSheet sh = workbook.getSheet("UserInputs");
TableModel model = table.getModel();
String value1 = model.getValueAt(0, 0).toString();
String value2 = model.getValueAt(0, 1).toString();
workbook.getSheet("UserInputs").getRow(8).getCell(1).setCellValue(value2);
FileOutputStream fileOut = new FileOutputStream(file);
workbook.write(fileOut);
fileOut.close();
workbook.close();
System.out.println("File written successfully");
}
catch(Exception e){
System.out.print(e);}
}
private static Object GetData(JTable table, int x, int y) {
return table.getValueAt(x, y).toString();
}
}
代码有问题吗?
您的代码仅覆盖 sheet UserInputs
中的一个单元格 B9
。如果这导致问题:
"Repaired Part: /xl/worksheets/sheet2.xml part with XML error. Load error. Line 2, column 0. Repaired Part: /xl/worksheets/sheet7.xml part with XML error. Load error. Line 2, column 0. Removed Records: Named range from /xl/workbook.xml part (Workbook) Removed Records: Table from /xl/tables/table1.xml part (Table)"
打开 Excel 中的工作簿时,sheet 中的单元格 B9
sheet UserInputs
是 header 中的单元格之一一个 Excel table object。此外,至少在 sheet2 和 sheet7 中使用了结构化 table 引用,例如 =Tablename[Columnname]
,用于公式中,并且还使用了此类结构化 table 引用在命名范围内。
所以如果 B9
in sheet sheet UserInputs
是 Excel table 的 header 单元格之一object 并且现在已更改,然后一开始 table 本身已损坏,因为其中一个列名称已更改而没有更新 table。但是所有结构化的 table 引用,例如 =Tablename[Columnname]
,都是损坏的,因为 Columnname
已经更改而没有更新所有这些公式。
更新 table header 可以使用 XSSFTable.updateHeaders。但是更新所有 sheet 甚至所有命名范围中所有公式中的所有结构化 table 引用将非常昂贵,甚至几乎不可能。所以我建议 而不是 更改 Excel table object 的 header 单元格。让 header 单元格保持原样,仅更改 table.
的内容范围
示例:
让我们有以下 IET.xlsx
文件:
如您所见,sheet UserInput
中有一个名为 Table1
的 table,header 位于第 9 行。
现在我们可以用 JTable
中的内容覆盖内容范围 B10:F[10+n]
,如下所示:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.*;
import org.apache.poi.ss.util.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
class ReadAndWriteExcelHavingTableObject {
static void writeToExcel(XSSFTable exceltable, JTable table) throws Exception {
int exceltableStartRow = exceltable.getStartRowIndex();
int exceltableStartCol = exceltable.getStartColIndex();
XSSFSheet sheet = (XSSFSheet)exceltable.getParent();
TableModel model = table.getModel();
int exceltableEndRow = exceltableStartRow + model.getRowCount(); //as much rows as are in the model
int exceltableEndCol = exceltable.getEndColIndex();
//write the content
for (int r = 0; r < model.getRowCount(); r++) {
for (int c = 0; c < exceltableEndCol - exceltableStartCol + 1; c++) {
XSSFRow row = sheet.getRow(exceltableStartRow + 1 + r);
if (row == null) row = sheet.createRow(exceltableStartRow + 1 + r);
XSSFCell cell = row.getCell(exceltableStartCol + c);
if (cell == null) cell = row.createCell(exceltableStartCol + c);
if (c < model.getColumnCount() && model.getValueAt(r, c) instanceof String) {
String str = (String)model.getValueAt(r, c);
cell.setCellValue(str);
} else if (c < model.getColumnCount() && model.getValueAt(r, c) instanceof Double) {
Double value = (Double)model.getValueAt(r, c);
cell.setCellValue(value);
} else if (c >= model.getColumnCount()) { //formula cells
XSSFCell firstCell = sheet.getRow(exceltableStartRow + 1).getCell(exceltableStartCol + c);
if (firstCell.getCellTypeEnum() == CellType.FORMULA) {
cell.setCellFormula(firstCell.getCellFormula());
}
}
}
}
//update the size of exceltable
exceltable.setCellReferences(new AreaReference(
new CellReference(exceltableStartRow, exceltableStartCol),
new CellReference(exceltableEndRow, exceltableEndCol),
SpreadsheetVersion.EXCEL2007));
}
public static void main(String[] args) throws Exception {
Object rowData[][] = {
{"Bob", 12.0, 3.0},
{"Alice", 34.0, 2.5},
{"Jack", 56.0, 2.0},
{"John", 78.0, 1.5}
};
Object columnNames[] = {"Name", "Amount", "Factor"};
DefaultTableModel model = new DefaultTableModel(rowData, columnNames);
JTable table = new JTable(model);
table.setModel(model);
File file = new File("IET.xlsx");
FileInputStream inputStream = new FileInputStream(file);
XSSFWorkbook workbook = (XSSFWorkbook)WorkbookFactory.create(inputStream);
XSSFTable exceltable = workbook.getTable("Table1");
writeToExcel(exceltable, table);
workbook.setForceFormulaRecalculation(true);
FileOutputStream fileOut = new FileOutputStream(file);
workbook.write(fileOut);
fileOut.close();
workbook.close();
}
}
结果将是:
并且由于没有更改 header,table 本身和所有结构化引用在此之后都不会损坏。
我写了一个代码来创建 jTable 并导出到 Excel.I works.But 当我打开 Excel 文件时文件没有完全恢复。 它显示了以下问题:
已修复部分:/xl/worksheets/sheet2.xml 部分有 XML 错误。加载错误。第 2 行,第 0 列。 已修复部分:/xl/worksheets/sheet7.xml 部分有 XML 错误。加载错误。第 2 行,第 0 列。 删除的记录:/xl/workbook.xml 部分的命名范围(工作簿) 删除的记录:Table 来自 /xl/tables/table1.xml 部分 (Table)
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.awt.event.ActionEvent;
public class GUI {
private static JTextField textField;
private static JTextField textField_1;
public static void main(String args[]) throws IOException {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Object rowData[][] = null ;
Object columnNames[] = { "Column One", "Column Two"};
DefaultTableModel model = new DefaultTableModel(rowData,columnNames);
frame.getContentPane().setLayout(null);
JTable table = new JTable(model);
table.setModel(model);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBounds(76, 106, 300, 200);
scrollPane.setVisible(true);
frame.getContentPane().add(scrollPane);
textField = new JTextField();
textField.setBounds(76, 21, 86, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
textField_1 = new JTextField();
textField_1.setBounds(76, 61, 86, 20);
frame.getContentPane().add(textField_1);
textField_1.setColumns(10);
JLabel lblNewLabel = new JLabel("Name");
lblNewLabel.setBounds(20, 24, 46, 14);
frame.getContentPane().add(lblNewLabel);
JLabel lblAge = new JLabel("Age");
lblAge.setBounds(20, 64, 46, 14);
frame.getContentPane().add(lblAge);
JButton btnNewButton = new JButton("Get Data");
btnNewButton.setBounds(235, 40, 89, 23);
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String name = textField.getText().toString();
int age = Integer.parseInt(textField_1.getText());
model.addRow(new Object[] {name,age});
Object obj1 = GetData(table, 0,0 );
System.out.println("Cell value of 1 column and 1 row :" + obj1);
Object obj2 = GetData(table, 0,1 );
System.out.println("Cell value of 2 column and 1 row :" + obj2);
}
});
frame.getContentPane().add(btnNewButton);
JButton btnNewButton_1 = new JButton("Excel");
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
try {
writeToExcel(table);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
btnNewButton_1.setBounds(340, 40, 89, 23);
frame.getContentPane().add(btnNewButton_1);
frame.setSize(455, 356);
frame.setVisible(true);
}
protected static void writeToExcel(JTable table) throws Exception {
try {
File file = new File("IET.xlsx");
FileInputStream inputStream = new FileInputStream(file);
XSSFWorkbook workbook = (XSSFWorkbook) WorkbookFactory.create(inputStream);
XSSFSheet sh = workbook.getSheet("UserInputs");
TableModel model = table.getModel();
String value1 = model.getValueAt(0, 0).toString();
String value2 = model.getValueAt(0, 1).toString();
workbook.getSheet("UserInputs").getRow(8).getCell(1).setCellValue(value2);
FileOutputStream fileOut = new FileOutputStream(file);
workbook.write(fileOut);
fileOut.close();
workbook.close();
System.out.println("File written successfully");
}
catch(Exception e){
System.out.print(e);}
}
private static Object GetData(JTable table, int x, int y) {
return table.getValueAt(x, y).toString();
}
}
代码有问题吗?
您的代码仅覆盖 sheet UserInputs
中的一个单元格 B9
。如果这导致问题:
"Repaired Part: /xl/worksheets/sheet2.xml part with XML error. Load error. Line 2, column 0. Repaired Part: /xl/worksheets/sheet7.xml part with XML error. Load error. Line 2, column 0. Removed Records: Named range from /xl/workbook.xml part (Workbook) Removed Records: Table from /xl/tables/table1.xml part (Table)"
打开 Excel 中的工作簿时,sheet 中的单元格 B9
sheet UserInputs
是 header 中的单元格之一一个 Excel table object。此外,至少在 sheet2 和 sheet7 中使用了结构化 table 引用,例如 =Tablename[Columnname]
,用于公式中,并且还使用了此类结构化 table 引用在命名范围内。
所以如果 B9
in sheet sheet UserInputs
是 Excel table 的 header 单元格之一object 并且现在已更改,然后一开始 table 本身已损坏,因为其中一个列名称已更改而没有更新 table。但是所有结构化的 table 引用,例如 =Tablename[Columnname]
,都是损坏的,因为 Columnname
已经更改而没有更新所有这些公式。
更新 table header 可以使用 XSSFTable.updateHeaders。但是更新所有 sheet 甚至所有命名范围中所有公式中的所有结构化 table 引用将非常昂贵,甚至几乎不可能。所以我建议 而不是 更改 Excel table object 的 header 单元格。让 header 单元格保持原样,仅更改 table.
的内容范围示例:
让我们有以下 IET.xlsx
文件:
如您所见,sheet UserInput
中有一个名为 Table1
的 table,header 位于第 9 行。
现在我们可以用 JTable
中的内容覆盖内容范围 B10:F[10+n]
,如下所示:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.*;
import org.apache.poi.ss.util.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
class ReadAndWriteExcelHavingTableObject {
static void writeToExcel(XSSFTable exceltable, JTable table) throws Exception {
int exceltableStartRow = exceltable.getStartRowIndex();
int exceltableStartCol = exceltable.getStartColIndex();
XSSFSheet sheet = (XSSFSheet)exceltable.getParent();
TableModel model = table.getModel();
int exceltableEndRow = exceltableStartRow + model.getRowCount(); //as much rows as are in the model
int exceltableEndCol = exceltable.getEndColIndex();
//write the content
for (int r = 0; r < model.getRowCount(); r++) {
for (int c = 0; c < exceltableEndCol - exceltableStartCol + 1; c++) {
XSSFRow row = sheet.getRow(exceltableStartRow + 1 + r);
if (row == null) row = sheet.createRow(exceltableStartRow + 1 + r);
XSSFCell cell = row.getCell(exceltableStartCol + c);
if (cell == null) cell = row.createCell(exceltableStartCol + c);
if (c < model.getColumnCount() && model.getValueAt(r, c) instanceof String) {
String str = (String)model.getValueAt(r, c);
cell.setCellValue(str);
} else if (c < model.getColumnCount() && model.getValueAt(r, c) instanceof Double) {
Double value = (Double)model.getValueAt(r, c);
cell.setCellValue(value);
} else if (c >= model.getColumnCount()) { //formula cells
XSSFCell firstCell = sheet.getRow(exceltableStartRow + 1).getCell(exceltableStartCol + c);
if (firstCell.getCellTypeEnum() == CellType.FORMULA) {
cell.setCellFormula(firstCell.getCellFormula());
}
}
}
}
//update the size of exceltable
exceltable.setCellReferences(new AreaReference(
new CellReference(exceltableStartRow, exceltableStartCol),
new CellReference(exceltableEndRow, exceltableEndCol),
SpreadsheetVersion.EXCEL2007));
}
public static void main(String[] args) throws Exception {
Object rowData[][] = {
{"Bob", 12.0, 3.0},
{"Alice", 34.0, 2.5},
{"Jack", 56.0, 2.0},
{"John", 78.0, 1.5}
};
Object columnNames[] = {"Name", "Amount", "Factor"};
DefaultTableModel model = new DefaultTableModel(rowData, columnNames);
JTable table = new JTable(model);
table.setModel(model);
File file = new File("IET.xlsx");
FileInputStream inputStream = new FileInputStream(file);
XSSFWorkbook workbook = (XSSFWorkbook)WorkbookFactory.create(inputStream);
XSSFTable exceltable = workbook.getTable("Table1");
writeToExcel(exceltable, table);
workbook.setForceFormulaRecalculation(true);
FileOutputStream fileOut = new FileOutputStream(file);
workbook.write(fileOut);
fileOut.close();
workbook.close();
}
}
结果将是:
并且由于没有更改 header,table 本身和所有结构化引用在此之后都不会损坏。