Question

Is it possible to get the datatype or format of a column or cell in a spreadsheet when you read it using cfspreadsheet?

I am converting spreadsheet data from an excel spreadsheet to a database table. Thus far I just format everything as varchars, but it would be good if I could specify dates as dates and integers as integers.

Was it helpful?

Solution

Unfortunately, not using cfspreadsheet or the built in spreadsheet functions. They only return what is displayed, not the underlying values. However you could roll your own by tapping into the underlying POI workbook.

A few things to keep in mind:

  • Unlike database tables, spreadsheet columns can contain a mix of data types. Just because the first cell contains a date is no guarantee all cells in that column contain dates too. So as with any import, be sure to validate all values before inserting them into your database table.
  • These methods only include populated rows and cells. Blank rows and cells are skipped. So the column values are not always contiguous.
  • Sheet, row and column indexes are zero (0) based

To do the processing, just grab the desired sheet and iterate through the rows and cells. As you loop through the columns, check the cell type and extract the raw value (ie date, string, number, ...)

Source: Busy Developers' Guide to HSSF and XSSF Features

<cfscript>
// get the sheet you want to read
cfSheet = SpreadSheetRead("c:/path/to/somefile.xls"); 
workbook = cfSheet.getWorkBook();
sheetIndex = workbook.getActiveSheetIndex();
sheet = workbook.getSheetAt( sheetIndex );

// utility used to distinguish between dates and numbers
dateUtil = createObject("java", "org.apache.poi.ss.usermodel.DateUtil");

// process the rows and columns
rows = sheet.rowIterator();
while (rows.hasNext()) {
    currentRow = rows.next();
    data = {}; 

    cells = currentRow.cellIterator();
    while (cells.hasNext()) { 
        currentCell = cells.next();

        col = {};
        col.value  = "";
        col.type   = "";
        col.column = currentCell.getColumnIndex()+ 1;
        col.row    = currentCell.getRowIndex()+ 1;

        if (currentCell.getCellType() EQ currentCell.CELL_TYPE_STRING) {
               col.value = currentCell.getRichStringCellValue().getString();
            col.type = "string";
        }
        else if (currentCell.getCellType() EQ currentCell.CELL_TYPE_NUMERIC) {
            if (DateUtil.isCellDateFormatted(currentCell)) {
                 col.value = currentCell.getDateCellValue();
                 col.type = "date";
            } 
            else {
                 col.value = currentCell.getNumericCellValue();
                 col.type = "number";
            }
        }
        else if (currentCell.getCellType() EQ currentCell.CELL_TYPE_BOOLEAN) {
            col.value = currentCell.getBooleanCellValue();
            col.type = "boolean";
        }
        // ... handle other types CELL_TYPE_BLANK, CELL_TYPE_ERROR, CELL_TYPE_FORMULA

        data["COL"& col.column] = col;
    }

    // this row is finished. display all values
    WriteDump(data);
}
</cfscript>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top