/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved. * This code is licensed under the GPL 2.0 license, availible at the root * application directory. */ package org.geoserver.wfs.response; import java.io.IOException; import java.io.OutputStream; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import javax.xml.namespace.QName; import net.opengis.wfs.FeatureCollectionType; import net.opengis.wfs.GetFeatureType; import net.opengis.wfs.QueryType; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.geoserver.ows.util.OwsUtils; import org.geoserver.platform.Operation; import org.geoserver.platform.ServiceException; import org.geoserver.wfs.WFSGetFeatureOutputFormat; import org.geotools.feature.FeatureCollection; import org.geotools.feature.FeatureIterator; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.AttributeDescriptor; /** * WFS output format for a GetFeature operation in which the outputFormat is "excel". * * @author Sebastian Benthall, OpenGeo, seb@opengeo.org */ public class ExcelOutputFormat extends WFSGetFeatureOutputFormat { static final int EXCELL_CELL_CHAR_LIMIT = (int) Math.pow(2,15) - 1; //32,767 static final String STRING_LENGTH_WARNING = "DATA TRUNCATED (EXCEEDS EXCEL LIMIT)"; public ExcelOutputFormat() { //this is the name of your output format, it is the string // that will be used when requesting the format in a // GEtFeature request: // ie ;.../geoserver/wfs?request=getfeature&outputFormat=myOutputFormat super("excel"); } /** * @return "application/msexcel"; */ @Override public String getMimeType(Object value, Operation operation) throws ServiceException { return "application/msexcel"; } @Override public String[][] getHeaders(Object value, Operation operation) throws ServiceException { GetFeatureType request = (GetFeatureType) OwsUtils.parameter(operation.getParameters(), GetFeatureType.class); String outputFileName = ((QName) ((QueryType) request.getQuery().get(0)).getTypeName().get(0)) .getLocalPart(); return (String[][]) new String[][] { { "Content-Disposition", "attachment; filename=" + outputFileName + ".xls" } }; } /** * @see WFSGetFeatureOutputFormat#write(Object, OutputStream, Operation) */ @Override protected void write(FeatureCollectionType featureCollection, OutputStream output, Operation getFeature) throws IOException, ServiceException { //Create the workbook HSSFWorkbook wb = new HSSFWorkbook(); for (Iterator it = featureCollection.getFeature().iterator(); it.hasNext();) { FeatureCollection<SimpleFeatureType, SimpleFeature> fc = (FeatureCollection<SimpleFeatureType, SimpleFeature>) it.next(); // create the sheet for this feature collection HSSFSheet sheet = wb.createSheet(fc.getSchema().getTypeName()); // write out the header HSSFRow header = sheet.createRow((short) 0); SimpleFeatureType ft = (SimpleFeatureType) fc.getSchema(); HSSFCell cell; cell = header.createCell(0); cell.setCellValue(new HSSFRichTextString("FID")); for ( int i = 0; i < ft.getAttributeCount(); i++ ) { AttributeDescriptor ad = ft.getDescriptor(i); cell = header.createCell(i+1); cell.setCellValue(new HSSFRichTextString(ad.getLocalName())); } // write out the features FeatureIterator<SimpleFeature> i = fc.features(); int r = 0; // row index try { HSSFRow row; while( i.hasNext() ) { r++; //start at 1, since header is at 0 SimpleFeature f = i.next(); row = sheet.createRow((short) r); cell = row.createCell(0); cell.setCellValue(new HSSFRichTextString(f.getID())); for ( int j = 0; j < f.getAttributeCount(); j++ ) { Object att = f.getAttribute( j ); if ( att != null ) { cell = row.createCell(j+1); if(att instanceof Number) { cell.setCellValue(((Number) att).doubleValue()); } else if(att instanceof Date) { cell.setCellValue((Date) att); } else if(att instanceof Calendar) { cell.setCellValue((Calendar) att); } else if(att instanceof Boolean) { cell.setCellValue((Boolean) att); } else { // ok, it seems we have no better way than dump it as a string String stringVal = att.toString(); // if string length > excel cell limit, truncate it and warn the // user, otherwise excel workbook will be corrupted if (stringVal.length() > EXCELL_CELL_CHAR_LIMIT) { stringVal = STRING_LENGTH_WARNING + " " + stringVal.substring(0, EXCELL_CELL_CHAR_LIMIT - STRING_LENGTH_WARNING.length() - 1); } cell.setCellValue(new HSSFRichTextString(stringVal)); } } } } } finally { fc.close( i ); } } //write to output wb.write(output); } }