Project

General

Profile

Download (7.58 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy 
5
* http://www.e-taxonomy.eu
6
* 
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10

    
11
package eu.etaxonomy.cdm.common;
12

    
13
import java.io.FileNotFoundException;
14
import java.net.URI;
15
import java.text.DateFormat;
16
import java.text.Format;
17
import java.util.ArrayList;
18
import java.util.Date;
19
import java.util.HashMap;
20
import java.util.Locale;
21

    
22
import org.apache.log4j.Logger;
23
import org.apache.poi.hssf.usermodel.HSSFCell;
24
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
25
import org.apache.poi.hssf.usermodel.HSSFRow;
26
import org.apache.poi.hssf.usermodel.HSSFSheet;
27
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
28
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
29

    
30
/**
31
 * @author n.hoffmann
32
 * @created 18.11.2008
33
 * @version 1.0
34
 */
35
public class ExcelUtils {
36
	private static final Logger logger = Logger.getLogger(ExcelUtils.class);
37
	
38
    /** Reads all rows of an Excel worksheet */
39
    public static ArrayList<HashMap<String, String>> parseXLS(URI uri) throws FileNotFoundException {
40
    	return parseXLS(uri, null);
41
    }
42

    
43
    
44
	/** Reads all rows of an Excel worksheet */
45
    public static ArrayList<HashMap<String, String>> parseXLS(URI uri, String worksheetName) throws FileNotFoundException {
46
    	
47
    	ArrayList<HashMap<String, String>> recordList = new ArrayList<HashMap<String, String>>();
48

    
49
    	try {
50
    		POIFSFileSystem fs = new POIFSFileSystem(UriUtils.getInputStream(uri));
51
    		HSSFWorkbook wb = new HSSFWorkbook(fs);
52
    		HSSFSheet sheet;
53
    		if (worksheetName == null){
54
    			sheet = wb.getSheetAt(0);	
55
    		}else{
56
    			sheet = wb.getSheet(worksheetName);
57
    		}
58
    		
59
    		if (sheet== null){
60
    			if (worksheetName != null){
61
    				logger.debug(worksheetName + " not provided!");
62
    			}
63
    		}else{
64
	    		HSSFRow row;
65
	    		HSSFCell cell;
66
	
67
	    		int rows; // No of rows
68
	    		rows = sheet.getPhysicalNumberOfRows();
69
				if(logger.isDebugEnabled()) { logger.debug("Number of rows: " + rows); }
70
	
71
	    		int cols = 0; // Number of columns
72
	    		int tmp = 0;
73
	
74
	    		// This trick ensures that we get the data properly even if it doesn't start from first few rows
75
	    		for(int i = 0; i < 10 || i < rows; i++) {
76
	    			row = sheet.getRow(i);
77
	     			if(row != null) {
78
	    				tmp = sheet.getRow(i).getPhysicalNumberOfCells();
79
	    				if(tmp > cols){
80
	    					cols = tmp;
81
	    				}
82
	    			}
83
	    		}
84
    		
85
    		
86
	    		//first row
87
	    		ArrayList<String> columns = new ArrayList<String>();
88
	    		row = sheet.getRow(0);
89
	    		for (int c = 0; c < cols; c++){
90
	    			cell = row.getCell(c);
91
					if(cell != null) {
92
						columns.add(cell.toString());
93
						if(logger.isDebugEnabled()) { logger.debug("Cell #" + c + ": " + cell.toString()); }
94
					} else {
95
						if(logger.isDebugEnabled()) { logger.debug("Cell #" + c + " is null"); }
96
					}
97
	    		}
98
	    		
99
	    		//value rows
100
	    		for(int r = 1; r < rows; r++) {
101
	    			row = sheet.getRow(r);
102
	    			HashMap<String, String> headers = new HashMap<String, String>();
103
	    			boolean notEmpty = checkIsEmptyRow(row);
104
	    			if(notEmpty) {
105
	    				for(int c = 0; c < cols; c++) {
106
	    					cell = row.getCell(c);
107
	    					if(cell != null) {
108
	    						if (c >= columns.size()){
109
	    							String message = "Cell has no header. There are only %d headers but more not-null cells in approx. row %d. Cell is neglected.";
110
	    							message = String.format(message, columns.size(),row.getRowNum());
111
	    							logger.warn(message);
112
	    						}else{
113
	    							if(logger.isDebugEnabled()) { logger.debug(String.format("Cell #%d: %s", c, cell.toString())); }
114
	    							headers.put(columns.get(c), getCellValue(cell));	
115
	    						}
116
	    					} else {
117
	    						if(logger.isDebugEnabled()) { logger.debug("Cell #" + c + " is null"); }
118
	    					}
119
	    				}
120
	    			}
121
	    			recordList.add(headers);
122
	    		}
123
    		}
124
    	} catch(FileNotFoundException fne) {
125
    		throw new FileNotFoundException(uri.toString());
126
    	} catch(Exception ioe) {
127
    		logger.error("Error reading the Excel file.");
128
    		ioe.printStackTrace();
129
    	}
130
    	return recordList;
131
    }
132

    
133

    
134
	private static String getCellValue(HSSFCell cell) {
135
		try {
136
			if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING ){
137
				return cell.getStringCellValue();
138
			}else if (cell.getCellType() == HSSFCell.CELL_TYPE_BLANK){
139
				return "";
140
			}else if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
141
				return getNumericCellValue(cell);
142
			}else if (cell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN){
143
				Boolean cellValue = cell.getBooleanCellValue();
144
				String value = String.valueOf(cellValue);
145
				return value;
146
			}else if (cell.getCellType() == HSSFCell.CELL_TYPE_ERROR){
147
				return "-error-";
148
			}else if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA){
149
				try {
150
					String strValue = cell.getStringCellValue();
151
					if ("".equals(strValue)){
152
						strValue = getNumericCellValue(cell);
153
					}
154
					return strValue;
155
				} catch (Exception e) {
156
					String message = "Formula cell (%s) can't be transformed to string";
157
					message = String.format(message, getExcelCellString(cell));
158
					throw new RuntimeException(message, e);
159
				}
160
			}else{
161
				return cell.toString();
162
			}
163
		} catch (Exception e) {
164
			String message = "Error occurred while reading Excel cell '%s' . Use toString() instead. Error: %s";
165
			message = String.format(message,getExcelCellString(cell) ,e.getLocalizedMessage());
166
			logger.warn(message);
167
			return cell.toString();
168
		}
169
	}
170

    
171
	public static String getExcelCellString(HSSFCell cell){
172
		String result = "%s%s";
173
		result = String.format(result, getExcelColString(cell.getColumnIndex()), cell.getRowIndex());
174
		return result;
175
	}
176
	
177
	private static String getExcelColString(int colNr){
178
		int first = colNr / 26;
179
		int second = colNr % 26;
180
//		char a = Integer.valueOf(first).shortValue();
181
		String firstStr = String.valueOf((first > 0 ? (char)(first +64) :""));
182
		String secondStr = String.valueOf((char)(second + 64));
183
		return firstStr +  secondStr;
184
	}
185
	
186

    
187
	/**
188
	 * Returns the numeric cell value. In case the cell is formatted as
189
	 * a date it returns a date (using the dates toString() method.
190
	 * @param cell
191
	 * @return
192
	 */
193
	private static String getNumericCellValue(HSSFCell cell) {
194
		Double number = cell.getNumericCellValue();
195
//		HSSFCellStyle style = cell.getCellStyle();
196
//		String dataFormatString = style.getDataFormatString();
197
//		int index = style.getIndex();
198
		HSSFDataFormatter formatter = new HSSFDataFormatter();
199
//		Format defFormat = formatter.getDefaultFormat(cell);
200
		Format format = formatter.createFormat(cell);
201
//		String v = formatter.formatCellValue(cell);
202
		if (format != null && format instanceof DateFormat){
203
			//TODO use ISO or similar format once TimePeriod knows how to parse this
204
//			String result = formatter.formatCellValue(cell);
205
			Date date = cell.getDateCellValue();
206
			Locale locale = Locale.GERMAN;
207
			DateFormat df = DateFormat.getDateInstance(2,locale);
208
			String result = df.format(date); //result of type dd.mm.yyyy
209
//			String result = date.toString();
210
			
211
			return result;
212
		}
213
//		System.out.println(d);
214

    
215
		if (number.intValue() == number){
216
			return String.valueOf(number.intValue());
217
		}else{
218
			return String.valueOf(number);
219
		}
220
	}
221

    
222

    
223
	/**
224
	 * Returns false, if row is null or has no values
225
	 * @param row
226
	 * @param notEmpty
227
	 * @return
228
	 */
229
	private static boolean checkIsEmptyRow(HSSFRow row) {
230
		if (row == null){
231
			return false;
232
		}
233
		boolean notEmpty = false;
234
		for (int j = 0; j<row.getLastCellNum(); j++){
235
			if (row.getCell(j) != null){
236
				notEmpty = true;
237
			}
238
		}
239
		return notEmpty;
240
	}
241
	
242
}
(4-4/11)