2017-12-26 82 views
0

jTable을 만들고 Excel.I로 내보내는 코드를 작성했습니다.하지만 Excel 파일을 열면 파일이 완전히 복구되지 않습니다. 다음과 같은 문제가 표시됩니다 :Jtable을 Excel로 변환, 업데이트 된 파일 오류

수리 된 부품 : /xl/worksheets/sheet2.xml 부분에 XML 오류가 있습니다. 로드 오류. 2 행, 0 열 수리 된 부품 : XML 오류가있는 /xl/worksheets/sheet7.xml 부품. 로드 오류. 2 호선, 열 0 는 기록 제거됨 : /xl/workbook.xml 부분에서 명명 된 범위 (통합 문서) 제거 된 레코드 :

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(); 
} 
    } 

는 /xl/tables/table1.xml 부분에서 테이블 (표)이 있습니까 코드에 문제가 있습니까?

+1

아마도 직접적인 문제는 아니지만 Java GUI는 다른 로케일에서 다른 PLAF를 사용하여 다른 OS ', 화면 크기, 화면 해상도 등에서 작동해야합니다. 따라서, 픽셀 완벽한 레이아웃에 도움이되지 않습니다. 대신 레이아웃 관리자 또는 [조합] (http://stackoverflow.com/a/5630271/418556)과 [공백] 레이아웃 채우기 및 테두리 (http://stackoverflow.com/a/17874718/)를 사용하십시오. 418556). –

+0

'workbook.write (fileOut);이 (가)'workbook.write (fileOut);가 아니어야합니다. fileOut.flush();'? –

+0

'UserInputs'시트의 셀 'B9'이 테이블 객체의 제목 셀인 경우에만 '제거 된 레코드 : Table from /xl/tables/table1.xml part (Table)'을 재생산 할 수 있습니다. 시트. 하지만 왜 JTable의 컨텐츠 셀 내용으로 Excel 테이블의 제목을 덮어 쓰려고합니까? 그래서 도움을 얻으려면 'IET.xlsx'에 어떤 내용이 담겨 있는지와 그 내용으로 정확히 무엇을하려고 하는지를 설명해야합니다. –

답변

0

코드에서 한 셀 B9을 (를) UserInputs (으)로 덮어 쓰게됩니다. 이로 인해 문제가 발생하는 경우 :

"수리 된 부품 : /xl/worksheets/sheet2.xml 부분에 XML 오류가 있습니다. 오류 2 행의 0 열 오류가있는 부분 : /xl/worksheets/sheet7.xml 부분과 XML 오류 : 2 번째 줄, 0 번째 줄. 제거 된 레코드 : /xl/workbook.xml 부분 (통합 문서)의 명명 된 범위 제거 된 레코드 : /xl/tables/table1.xml 부분 (표)의 표 "

Excel에서 통합 문서를 여는 동안 시트 UserInputsB9 셀은 Excel 테이블 개체의 머리글 셀 중 하나입니다. 또한 적어도 sheet2와 sheet7에는 수식에 사용 된 =Tablename[Columnname]과 같은 구조화 된 테이블 참조가 있으며 그러한 구조화 된 테이블 참조는 명명 된 범위에서도 사용됩니다.

시트 시트 UserInputs이 Excel 테이블 개체의 머리글 셀 중 하나이며 지금 변경된 경우 열 이름 중 하나가 테이블을 업데이트하지 않고 변경 되었기 때문에 처음에는 테이블 자체가 손상되었습니다. 그러나 Columnname이 모든 수식을 업데이트하지 않고 변경 되었기 때문에 =Tablename[Columnname]과 같은 모든 구조화 된 테이블 참조가 손상되었습니다.

XSSFTable.updateHeaders을 사용하면 테이블 헤더를 업데이트 할 수 있습니다. 그러나 모든 시트의 모든 수식에서 심지어 모든 명명 된 범위의 모든 수식에서 모든 구조화 된 테이블 참조를 업데이트하는 것은 거의 불가능할 때까지 매우 비쌉니다. 따라서 Excel 테이블 개체의 머리글 셀을 변경하려면 이 아닌을 사용하는 것이 좋습니다. 표 셀을 그대로두고 표의 내용 범위 만 변경하십시오.

예 :

이의 다음 IET.xlsx 파일을 보자 :

enter image description here

보시다시피,이 시트 UserInputTable1라는 이름의 테이블이 있고 헤더 행 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); 
    workbook.close(); 

} 
} 

결과가 될 것입니다 :

enter image description here

없이 헤더 이후

이 변경, 테이블 자체를 이 후에 모든 구조화 된 참조가 손상되지 않습니다.