source: trunk/grails-app/services/nl/tno/metagenomics/imports/ImporterService.groovy @ 2

Last change on this file since 2 was 2, checked in by robert@…, 8 years ago

Initial import of basic functionality

File size: 5.8 KB
RevLine 
[2]1/**
2 * Importer service
3 *
4 * The importer service handles the import of tabular, comma delimited and Excel format
5 * based files.
6 *
7 * @package     importer
8 * @author      t.w.abma@umcutrecht.nl
9 * @since       20100126
10 *
11 * Revision information:
12 * $Rev: 1326 $
13 * $Author: t.w.abma@umcutrecht.nl $
14 * $Date: 2010-12-28 09:15:43 +0100 (Tue, 28 Dec 2010) $
15 */
16
17package nl.tno.metagenomics.imports
18
19import org.apache.poi.ss.usermodel.*
20import org.apache.poi.xssf.usermodel.*
21
22import nl.tno.metagenomics.*
23
24class ImporterService {
25
26        boolean transactional = true
27
28        /**
29         * @param is input stream representing the (workbook) resource
30         * @return high level representation of the workbook
31         */
32        Workbook getWorkbook(InputStream is) {
33                WorkbookFactory.create(is)
34        }
35
36        /**
37         * @param wb high level representation of the workbook
38         * @param sheetindex sheet to use within the workbook
39         * @return header representation as a MappingColumn hashmap
40         */
41        def getHeaders(Workbook wb, int sheetIndex, int headerrow) {
42                if( wb == null )
43                        throw new Exception( "No workbook given" );
44                       
45                if( sheetIndex >= wb.getNumberOfSheets() )
46                        throw new Exception( "Sheet with index " + sheetIndex + " doesn't exist. Workbook has " + wb.getNumberOfSheets() + " sheets." )
47               
48                Sheet sheet = wb.getSheetAt(sheetIndex)
49                def header = [:]
50
51                def df = new DataFormatter()
52               
53                // Determine the right row
54                if( headerrow > (sheet.getLastRowNum() - sheet.getLastRowNum()) )
55                        throw new Exception( "Row with index " + headerrow + " doesn't exist. Sheet has " + ( sheet.getLastRowNum() + 1 ) + " sheets." )
56
57                Row sheetrow = sheet.getRow(headerrow)
58                       
59                (0..sheetrow.getLastCellNum() -1 ).each { columnindex ->
60                        def headercell = sheet.getRow( headerrow + sheet.getFirstRowNum() ).getCell(columnindex)
61                       
62                        header[columnindex] = df.formatCellValue(headercell);
63
64                } // end of cell loop
65                return header
66        }
67
68        /**
69         * This method is meant to return a matrix of the rows and columns
70         * used in the preview
71         *
72         * @param wb workbook object
73         * @param sheetindex sheet index used
74         * @param rows amount of rows returned
75         * @return two dimensional array (matrix) of Cell objects
76         */
77
78        Object[][] getDatamatrix(Workbook wb, def headers, int sheetIndex, int datamatrix_start, int count) {
79                if( wb == null )
80                        throw new Exception( "No workbook given" );
81               
82                if( sheetIndex >= wb.getNumberOfSheets() )
83                        throw new Exception( "Sheet with index " + sheetIndex + " doesn't exist. Workbook has " + wb.getNumberOfSheets() + " sheets." )
84
85                def sheet = wb.getSheetAt(sheetIndex)
86                def rows  = []
87                def df = new DataFormatter()
88
89                // Determine the max number of rows to export
90                def numRowsInSheet = sheet.getLastRowNum() - sheet.getFirstRowNum() + 1;
91                def maxCount = numRowsInSheet - datamatrix_start
92                count = Math.min( count, maxCount )
93
94                // walk through all rows
95                def startrow = sheet.getFirstRowNum() + datamatrix_start
96                for( def rowindex = startrow; rowindex < startrow + count; rowindex++ ) {
97                        Row excelRow = sheet.getRow(rowindex)
98
99                        def row = []
100                       
101                        (0..headers.size()-1).each { columnindex ->
102                                def c = excelRow.getCell(columnindex, Row.CREATE_NULL_AS_BLANK)
103                                row << c
104                        }
105
106                        rows << row
107                }
108
109                return rows
110        }
111
112        /**
113         * Method to read data from a workbook and to import data into a two dimensional
114         * array
115         *
116         * @param wb POI horrible spreadsheet formatted workbook object
117         * @param mcmap linked hashmap (preserved order) of MappingColumns
118         * @param sheetindex sheet to use when using multiple sheets
119         * @param rowindex first row to start with reading the actual data (NOT the header)
120         * @return two dimensional array containing records (with entities)
121         *
122         * @see dbnp.importer.MappingColumn
123         */
124        def importData(Workbook wb, int sheetindex, int rowindex, mcmap) {
125                def sheet = wb.getSheetAt(sheetindex)
126                def table = []
127                def failedcells = [] // list of records
128
129                // walk through all rows and fill the table with records
130                (rowindex..sheet.getLastRowNum()).each { i ->
131                        // Create an entity record based on a row read from Excel and store the cells which failed to be mapped
132                        def (record, failed) = createRecord(template_id, sheet.getRow(i), mcmap)
133
134                        // Add record with entity and its values to the table
135                        table.add(record)
136
137                        // If failed cells have been found, add them to the failed cells list
138                        if (failed?.importcells?.size()>0) failedcells.add(failed)
139                }
140
141                return [table,failedcells]
142        }
143
144        /** Method to put failed cells back into the datamatrix. Failed cells are cell values
145         * which could not be stored in an entity (e.g. Humu Supiuns in an ontology field).
146         * Empty corrections should not be stored
147         *
148         * @param datamatrix two dimensional array containing entities and possibly also failed cells
149         * @param failedcells list with maps of failed cells in [mappingcolumn, cell] format
150         * @param correctedcells map of corrected cells in [cellhashcode, value] format
151         **/
152        def saveCorrectedCells(datamatrix, failedcells, correctedcells) {
153
154                // Loop through all failed cells (stored as
155                failedcells.each { record ->
156                        record.value.importcells.each { cell ->
157
158                                // Get the corrected value
159                                def correctedvalue = correctedcells.find { it.key.toInteger() == cell.getIdentifier()}.value
160
161                                // Find the record in the table which the mappingcolumn belongs to
162                                def tablerecord = datamatrix.find { it.hashCode() == record.key }
163
164                                // Loop through all entities in the record and correct them if necessary
165                                tablerecord.each { rec ->
166                                        rec.each { entity ->
167                                                try {
168                                                        // Update the entity field
169                                                        entity.setFieldValue(cell.mappingcolumn.property, correctedvalue)
170                                                        //println "Adjusted " + cell.mappingcolumn.property + " to " + correctedvalue
171                                                }
172                                                catch (Exception e) {
173                                                        //println "Could not map corrected ontology: " + cell.mappingcolumn.property + " to " + correctedvalue
174                                                }
175                                        }
176                                } // end of table record
177                        } // end of cell record
178                } // end of failedlist
179        }
180
181
182
183}
Note: See TracBrowser for help on using the repository browser.