/
ExcelOutputFormat.java
177 lines (148 loc) · 7.01 KB
/
ExcelOutputFormat.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/* 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 org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.geoserver.config.GeoServer;
import org.geoserver.platform.Operation;
import org.geoserver.platform.ServiceException;
import org.geoserver.wfs.WFSGetFeatureOutputFormat;
import org.geoserver.wfs.request.FeatureCollectionResponse;
import org.geoserver.wfs.request.GetFeatureRequest;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
/**
* Abstract base class for Excel WFS output format
*
* @author Sebastian Benthall, OpenGeo, seb@opengeo.org and Shane StClair, Axiom Consulting,
* shane@axiomalaska.com
*/
public abstract class ExcelOutputFormat extends WFSGetFeatureOutputFormat {
private static Logger log = Logger.getLogger(ExcelOutputFormat.class);
protected static int CELL_CHAR_LIMIT = (int) Math.pow(2, 15) - 1; // 32,767
protected static String TRUNCATE_WARNING = "DATA TRUNCATED";
protected int rowLimit;
protected int colLimit;
protected String fileExtension;
protected String mimeType;
public ExcelOutputFormat(GeoServer gs, String formatName) {
super(gs, formatName);
}
protected abstract Workbook getNewWorkbook();
/**
* @return mime type;
*/
@Override
public String getMimeType(Object value, Operation operation) throws ServiceException {
return mimeType;
}
@Override
public String getAttachmentFileName(Object value, Operation operation) {
GetFeatureRequest request = GetFeatureRequest.adapt(operation.getParameters()[0]);
String outputFileName = request.getQueries().get(0).getTypeNames().get(0).getLocalPart();
return outputFileName + "." + fileExtension;
}
@Override
public String getPreferredDisposition(Object value, Operation operation) {
return DISPOSITION_ATTACH;
}
/**
* @see WFSGetFeatureOutputFormat#write(Object, OutputStream, Operation)
*/
@Override
protected void write(FeatureCollectionResponse featureCollection, OutputStream output,
Operation getFeature) throws IOException ,ServiceException {
// Create the workbook
Workbook wb = getNewWorkbook();
CreationHelper helper = wb.getCreationHelper();
ExcelCellStyles styles = new ExcelCellStyles(wb);
for (Iterator it = featureCollection.getFeature().iterator(); it.hasNext();) {
SimpleFeatureCollection fc = (SimpleFeatureCollection) it.next();
// create the sheet for this feature collection
Sheet sheet = wb.createSheet(fc.getSchema().getTypeName());
// write out the header
Row header = sheet.createRow(0);
SimpleFeatureType ft = fc.getSchema();
Cell cell;
cell = header.createCell(0);
cell.setCellValue(helper.createRichTextString("FID"));
for (int i = 0; i < ft.getAttributeCount() && i < colLimit; i++) {
AttributeDescriptor ad = ft.getDescriptor(i);
cell = header.createCell(i + 1);
cell.setCellValue(helper.createRichTextString(ad.getLocalName()));
cell.setCellStyle(styles.getHeaderStyle());
}
// write out the features
SimpleFeatureIterator i = fc.features();
int r = 0; // row index
try {
Row row;
while (i.hasNext()) {
r++; // start at 1, since header is at 0
row = sheet.createRow(r);
cell = row.createCell(0);
if (r == (rowLimit - 1) && i.hasNext()) {
// there are more features than rows available in this
// Excel format. write out a warning line and break
RichTextString rowWarning = helper.createRichTextString(TRUNCATE_WARNING
+ ": ROWS " + r + " - " + fc.size() + " NOT SHOWN");
cell.setCellValue(rowWarning);
cell.setCellStyle(styles.getWarningStyle());
break;
}
SimpleFeature f = i.next();
cell.setCellValue(helper.createRichTextString(f.getID()));
for (int j = 0; j < f.getAttributeCount() && j < colLimit; 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);
cell.setCellStyle(styles.getDateStyle());
} else if (att instanceof Calendar) {
cell.setCellValue((Calendar) att);
cell.setCellStyle(styles.getDateStyle());
} 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() > CELL_CHAR_LIMIT) {
stringVal = TRUNCATE_WARNING
+ " "
+ stringVal.substring(0, CELL_CHAR_LIMIT
- TRUNCATE_WARNING.length() - 1);
cell.setCellStyle(styles.getWarningStyle());
}
cell.setCellValue(helper.createRichTextString(stringVal));
}
}
}
}
} finally {
i.close();
}
}
// write to output
wb.write(output);
}
}