2017-02-09 172 views

回答

0

作爲我如何解決這個問題的更新。我使用controlsFX的SpreadsheetView來顯示我使用poi庫讀取的Excel表。所需要的只是讀取表格併爲視圖建立數據。我添加了下面的代碼。

/** 
* This class allows for the displaying of excel files within a window by 
* utilizing SpreadsheetView from controlsFX and the reading capabilities of  the POI library. 
* 
* Only usable for .xlsx files 
* 
* @author Theo 
* 
*/ 
public class ExcelView { 

    /** 
    * Path to Excel 
    */ 
    private String filePath; 

    private int sheetIndex; 

    private boolean editible; 

    private FileInputStream inStream; 
    private XSSFWorkbook poiWorkbook; 
    private XSSFSheet poiSheet; 

    private SpreadsheetView theView; 

    public ExcelView(String path, int sheetIndex ,boolean editable){ 
     filePath =path; 
     this.editible =editable; 
     this.sheetIndex =sheetIndex; 
    } 

    public ExcelView(String path, int sheetIndex){ 
     filePath =path; 
     this.editible =false; 
     this.sheetIndex = sheetIndex; 
    } 

    private void initializeView() throws Exception{ 
     GridBase grid = excelToGrid(); 

     theView = new SpreadsheetView(grid); 
     theView.setEditable(editible); 
    } 

    public SpreadsheetView getView() throws Exception{ 
     initializeView(); 
     return theView; 
    } 

    public void showInNewWindow(){ 
     Parent root; 
     try { 

     initializeView(); 

     root = theView; 
     Stage stage = new Stage(); 
     stage.setTitle(new File(filePath).getName()); 
     stage.setScene(new Scene(root, 450, 450)); 

     stage.getIcons().addAll(ResourceLoader.getIcons("Excel.ico"));  

     stage.show(); 

    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

/** 
* Updates the values in the view. This may happen after the Excel file has been 
* modified after the initial reading. 
* @throws Exception 
*/ 
public void updateView() throws Exception{ 
    GridBase newgrid = excelToGrid(); 

    theView.setGrid(newgrid); 
} 

/** 
* Creates a {@link GridBase} object from the excel file located at the path 
* @return 
* @throws Exception - when opening the file 
*/ 
private GridBase excelToGrid() throws Exception{ 

    // Read the Excel document and collect the rows 
    openBook(); 
    poiSheet = poiWorkbook.getSheetAt(sheetIndex); 

    int[] size = getSize(); 
    GridBase grid = new GridBase(size[0], size[1]); 

    ObservableList<ObservableList<SpreadsheetCell>> rows = FXCollections.observableArrayList(); 

    Row poiRow; 
    Cell cell; 
    String value; 
    FormulaEvaluator evaluator = poiWorkbook.getCreationHelper().createFormulaEvaluator(); 

    for (int row = 0; row < grid.getRowCount(); ++row) { 
     final ObservableList<SpreadsheetCell> list = FXCollections.observableArrayList(); 
     poiRow = poiSheet.getRow(row); 
     for (int column = 0; column < grid.getColumnCount(); ++column) { 

      cell = poiRow.getCell(column); 
      value = ExcelUtils.cellStringValue(evaluator,cell); 

      list.add(SpreadsheetCellType.STRING.createCell(row, column, 1, 1,value)); 
     } 
     rows.add(list); 
    } 
    grid.setRows(rows); 

    closeBook(); 

    return grid; 
} 

/** 
* Calculates the number of rows and columns in the sheet by looping 
* and reading all the things :) 
* @return the size as int[{rows, cols}] 
*/ 
private int[] getSize(){ 

    int numRows = 0; 
    int numCols =0; 

    int nullRowCounter = 0; 
    int nullColCounter = 0; 

    int maxNullRows = 6; 
    int maxNullCols = 6; 

    Row row; 
    Cell cell; 
    int localColCounter; 

    while(true){ 

     row= poiSheet.getRow(numRows); 
     numRows++; 

     // Check row... 
     if(row == null){ 
      nullRowCounter++; 
     } 
     else{ 
      nullRowCounter = 0; 
      // If row not null, check columns... 
      localColCounter = 0; 
      while(true){ 
       cell = row.getCell(localColCounter); 
       localColCounter++; 
       if(cell==null){ 
        nullColCounter++; 
       }else{ 
        nullColCounter = 0; 
       } 

       if(nullColCounter == maxNullCols){ 
        // reached max null cells 
        localColCounter -= maxNullCols; 

        if(localColCounter > numCols) 
         numCols = localColCounter; 

        break; 
        // go to next row... 
       } 

      } 
     } 

     if(nullRowCounter == maxNullRows){ 
      // reached max null rows 
      numRows -= maxNullRows; 

      break; 

     } 
    } 
    return new int[]{numRows, numCols}; 

} 

private void openBook() throws Exception{ 
    try { 
     File myFile = new File(filePath); 
     inStream = new FileInputStream(myFile); 

     poiWorkbook = new XSSFWorkbook (inStream); 

    }catch (Exception e) { 
     e.printStackTrace(); 
     throw e; 
    } 
} 

private void closeBook() throws Exception{ 


    try { 
     poiWorkbook.close(); 
     inStream.close(); 

    }catch (Exception e) { 
     e.printStackTrace(); 
     throw e; 
    } 
} 
} 
+0

這似乎是一個非常好的例子!也許你可以通過檢測Excel中的數據類型並根據它使用SpreadsheetCellType來改進它。如果需要,也可以檢測Excel格式並將其設置在單元格中。 – Maxoudela

+0

@Maxoudela謝謝:)我目前正在使用自定義方法將所有單元格值轉換爲字符串,以允許處理空單元格。但我相信,改變你的建議會帶來更好的顯示效果。我會將它添加到我的待辦事項列表中,並在完成時更新答案。 – TM00