public Map<Long,Subscriber> readFile(File file) throws IOException { 
		Map<Long,Subscriber> subscribers = new TreeMap<Long,Subscriber>();
		try {
			Workbook wb = WorkbookFactory.create(file);
			Sheet s = wb.getSheetAt(0);
			
			// Take first row, use to check order of fields
			Row firstRow = s.getRow(s.getFirstRowNum());
			FieldType[] order = new FieldType[firstRow.getLastCellNum() - firstRow.getFirstCellNum()];
			int j = 0; 
			for(int i = firstRow.getFirstCellNum(); i < firstRow.getLastCellNum(); i++, j++) {
				Cell c = firstRow.getCell(i);
				if(c != null) {
					if(c.getCellType() == Cell.CELL_TYPE_NUMERIC) {
						String val = new Integer(new Double(c.getNumericCellValue()).intValue()).toString();
						order[j] = FieldType.getFieldType(val);
					} else {
						order[j] = FieldType.getFieldType(c.getStringCellValue());
					}
				}
			}
			// Then iterate through the rest of the rows
			if(s.getLastRowNum() > 0) {
				// LastRowNum is 0-indexed, so add 1
				for(int i = s.getFirstRowNum()+1; i < s.getLastRowNum()+1; i++) {
					Row r = s.getRow(i);
					Subscriber sub = new Subscriber();
					j = 0;
					// LastCellNum is also 0-indexed
					for(int k = r.getFirstCellNum(); k < r.getLastCellNum()+1; k++, j++) {
						Cell c = r.getCell(k);
						if(c != null) {
							if(c.getCellType() == Cell.CELL_TYPE_NUMERIC) {
								String val = new Integer(new Double(c.getNumericCellValue()).intValue()).toString();
								sub.setByField(order[j], val);
							} else {
								sub.setByField(order[j], c.getStringCellValue());
							}
						}
					}
					subscribers.put(sub.getAbNr(),sub);
				}
			}
			return subscribers;
		} catch(InvalidFormatException ife) {
			// If the file was badly formatted
			throw new IOException(ife);
		}
	}