使用Apache-POI读取一定数量的列

时间:2012-12-20 19:45:12

标签: java apache-poi

这是我正在做的事情的主旨。

我正在创建一个ExcelProcessor对象,然后获取我在构造函数中指定的文件。在此之后,我检索书籍,行,然后检索行中的单元格。第一行具有每列保存数据的名称。不幸的是,如果任何单元格连续空白,它就会在那时停止处理。有没有办法说每行读取X个列数?

谢谢!

public class ExcelProcessor
{
    private static File xslFile;

    ExcelProcessor( String file )
    {
        xslFile = new File(file);
    }

    /**
     * creates an {@link HSSFWorkbook} the specified OS filename.
     */

    /**
     * Returns an XSSF Workbook object that can be queried. 
     * 
     * This method either returns a Workbook with the specified
     * file location or it will throw an IO Error.
     *
     * @return      the Excel Workbook 
     * @see         XSSFWB
     */

    private XSSFWorkbook readFile() throws IOException
    {
        return new XSSFWorkbook(new FileInputStream(xslFile));
    }

    /**
     * Returns all rows of the XSSF Workbook that is read in via the file system.
     * 
     * This method returns a XSSFRow array for processing
     *
     * @param   wb  the Excel workbook located on the file system
     * @return      Rows contained within the Excel Workbook
     * @see         XSSFRows
     */

    private XSSFRow[] retrieveRows(XSSFWorkbook wb)
    {
        XSSFSheet xslSheet = wb.getSheetAt(0);
        XSSFRow[] sheetRows = new XSSFRow[xslSheet.getLastRowNum()];

        for (int i = 0; i < xslSheet.getLastRowNum(); i++)
        {
            sheetRows[i] = xslSheet.getRow(i);
        }

        return sheetRows;
    }

    private XSSFWorkbook modifyRows(XSSFWorkbook wb)
    {
        return wb;
    }

    /**
     * Processes all rows of the XSSF Workbook that is read in via the file system.
     * Each Cell is pulled from the rows to create a structure needed for WQS 
     * Web Services.
     * 
     * This method returns a String array for all Cells pulled from the Rows
     *
     * @param   xslRow  Current row pulled from the XSL Workbook
     * @return      String Array of all Row Cell Values
     * @see         String[]
     */

    public String[] processRow(XSSFRow xslRow)
    {
        int totalCells = xslRow.getPhysicalNumberOfCells();
        System.out.println("Total Cells: " + totalCells);
        String[] cellValues = new String[totalCells];

        for (int i = 0; i < totalCells; i++)
        {
            XSSFCell currentCell = xslRow.getCell(i);
            String cellVal;
            try
            {
                cellVal = currentCell.getStringCellValue();
            }
            catch (Exception e)
            {
                System.out.println("Empty Cell");
                cellVal = "";
            }
            cellValues[i] = cellVal;
            System.out.println(cellVal);
        }

        return cellValues;
    }

    /**
     * Main method which creates an ExcelProcessor before handling the Excel
     * Spreadsheet given to the user.
     * 
     * @param args
     * @throws ParserConfigurationException
     * @throws SAXException
     */

    public static void main(String args[]) throws ParserConfigurationException, SAXException
    {
        ExcelProcessor driver = new ExcelProcessor("D:\\TestBook.xlsx");

        try
        {
            XSSFWorkbook xslWB = driver.readFile();
            XSSFRow[] xslRows = driver.retrieveRows(xslWB);
            ArrayList<String[]> rowCellVals = new ArrayList<String[]>();

            for (int r = 0; r < xslRows.length; r++)
            {
                rowCellVals.add(driver.processRow(xslRows[r]));
            }

            String sessionKey = WQSServices.sessionToken();
            System.out.println("Have the Session Key: " + sessionKey);
            WQSServices.uploadAttachment(sessionKey, rowCellVals);

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

}

2 个答案:

答案 0 :(得分:2)

使用getLastCellNum代替getPhysicalNumberOfCells返回单元格数量(不计算空单元格)

答案 1 :(得分:1)

首先,你不应该盲目地尝试将字符串作为单元格读取并捕获异常。相反,您应该检查文件中是否定义了它(是否为空?),并检查它的类型。您的工作表可能包含数字,并且它们不会存储为字符串,因此您当前的代码将跳过它们!

我建议您阅读POI快速指南的Iterating over Rows and CellsReading Cell Contents部分作为首发。然后,将代码更改为:

// Decide which rows to process
int rowStart = Math.min(15, sheet.getFirstRowNum());
int rowEnd = Math.max(1400, sheet.getLastRowNum());

for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
   Row r = sheet.getRow(rowNum);

   int lastColumn = Math.max(r.getLastCellNum(), MY_MINIMUM_COLUMN_COUNT);

   for (int cn = 0; cn < lastColumn; cn++) {
      Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL);
      if (c == null) {
         // The spreadsheet is empty in this cell
      } else {
         // Do something useful with the cell's contents
         switch (cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                System.out.println(cell.getRichStringCellValue().getString());
                break;
            case Cell.CELL_TYPE_NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    System.out.println(cell.getDateCellValue());
                } else {
                    System.out.println(cell.getNumericCellValue());
                }
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                System.out.println(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_FORMULA:
                System.out.println(cell.getCellFormula());
                break;
         }     
      }
   }
}