001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028:
029: /*
030: * Contributors:
031: * Mirko Wawrowsky - mawawrosky@users.sourceforge.net
032: */
033: package net.sf.jasperreports.engine.export;
034:
035: import java.io.File;
036: import java.io.FileOutputStream;
037: import java.io.IOException;
038: import java.io.OutputStream;
039: import java.io.OutputStreamWriter;
040: import java.io.StringWriter;
041: import java.io.Writer;
042: import java.util.List;
043: import java.util.StringTokenizer;
044:
045: import net.sf.jasperreports.engine.JRAbstractExporter;
046: import net.sf.jasperreports.engine.JRException;
047: import net.sf.jasperreports.engine.JRExporterParameter;
048: import net.sf.jasperreports.engine.JRPrintElement;
049: import net.sf.jasperreports.engine.JRPrintPage;
050: import net.sf.jasperreports.engine.JRPrintText;
051: import net.sf.jasperreports.engine.JasperPrint;
052: import net.sf.jasperreports.engine.util.JRStyledText;
053: import net.sf.jasperreports.engine.util.JRStyledTextParser;
054:
055: import org.xml.sax.SAXException;
056:
057: /**
058: * Exports a JasperReports document to CSV format. It has character output type and exports the document to a
059: * grid-based layout.
060: * @author Teodor Danciu (teodord@users.sourceforge.net)
061: * @version $Id: JRCsvExporter.java 1824 2007-08-23 14:19:12Z teodord $
062: */
063: public class JRCsvExporter extends JRAbstractExporter {
064:
065: /**
066: *
067: */
068: protected JRStyledTextParser styledTextParser = new JRStyledTextParser();
069:
070: /**
071: *
072: */
073: protected String delimiter = null;
074:
075: /**
076: *
077: */
078: protected String recordDelimiter = null;
079:
080: /**
081: *
082: */
083: protected Writer writer = null;
084: protected JRExportProgressMonitor progressMonitor = null;
085:
086: /**
087: *
088: */
089: public void exportReport() throws JRException {
090: progressMonitor = (JRExportProgressMonitor) parameters
091: .get(JRExporterParameter.PROGRESS_MONITOR);
092:
093: /* */
094: setOffset();
095:
096: /* */
097: setInput();
098:
099: /* */
100: if (!isModeBatch) {
101: setPageRange();
102: }
103:
104: String encoding = getStringParameterOrDefault(
105: JRExporterParameter.CHARACTER_ENCODING,
106: JRExporterParameter.PROPERTY_CHARACTER_ENCODING);
107:
108: delimiter = getStringParameterOrDefault(
109: JRCsvExporterParameter.FIELD_DELIMITER,
110: JRCsvExporterParameter.PROPERTY_FIELD_DELIMITER);
111:
112: recordDelimiter = getStringParameterOrDefault(
113: JRCsvExporterParameter.RECORD_DELIMITER,
114: JRCsvExporterParameter.PROPERTY_RECORD_DELIMITER);
115:
116: StringBuffer sb = (StringBuffer) parameters
117: .get(JRExporterParameter.OUTPUT_STRING_BUFFER);
118: if (sb != null) {
119: try {
120: writer = new StringWriter();
121: exportReportToWriter();
122: sb.append(writer.toString());
123: } catch (IOException e) {
124: throw new JRException(
125: "Error writing to StringBuffer writer : "
126: + jasperPrint.getName(), e);
127: } finally {
128: if (writer != null) {
129: try {
130: writer.close();
131: } catch (IOException e) {
132: }
133: }
134: }
135: } else {
136: writer = (Writer) parameters
137: .get(JRExporterParameter.OUTPUT_WRITER);
138: if (writer != null) {
139: try {
140: exportReportToWriter();
141: } catch (IOException e) {
142: throw new JRException("Error writing to writer : "
143: + jasperPrint.getName(), e);
144: }
145: } else {
146: OutputStream os = (OutputStream) parameters
147: .get(JRExporterParameter.OUTPUT_STREAM);
148: if (os != null) {
149: try {
150: writer = new OutputStreamWriter(os, encoding);
151: exportReportToWriter();
152: } catch (IOException e) {
153: throw new JRException(
154: "Error writing to OutputStream writer : "
155: + jasperPrint.getName(), e);
156: }
157: } else {
158: File destFile = (File) parameters
159: .get(JRExporterParameter.OUTPUT_FILE);
160: if (destFile == null) {
161: String fileName = (String) parameters
162: .get(JRExporterParameter.OUTPUT_FILE_NAME);
163: if (fileName != null) {
164: destFile = new File(fileName);
165: } else {
166: throw new JRException(
167: "No output specified for the exporter.");
168: }
169: }
170:
171: try {
172: os = new FileOutputStream(destFile);
173: writer = new OutputStreamWriter(os, encoding);
174: exportReportToWriter();
175: } catch (IOException e) {
176: throw new JRException(
177: "Error writing to file writer : "
178: + jasperPrint.getName(), e);
179: } finally {
180: if (writer != null) {
181: try {
182: writer.close();
183: } catch (IOException e) {
184: }
185: }
186: }
187: }
188: }
189: }
190: }
191:
192: /**
193: *
194: */
195: protected void exportReportToWriter() throws JRException,
196: IOException {
197: for (int reportIndex = 0; reportIndex < jasperPrintList.size(); reportIndex++) {
198: jasperPrint = (JasperPrint) jasperPrintList
199: .get(reportIndex);
200:
201: List pages = jasperPrint.getPages();
202: if (pages != null && pages.size() > 0) {
203: if (isModeBatch) {
204: startPageIndex = 0;
205: endPageIndex = pages.size() - 1;
206: }
207:
208: for (int i = startPageIndex; i <= endPageIndex; i++) {
209: if (Thread.currentThread().isInterrupted()) {
210: throw new JRException(
211: "Current thread interrupted.");
212: }
213:
214: JRPrintPage page = (JRPrintPage) pages.get(i);
215:
216: /* */
217: exportPage(page);
218: }
219: }
220: }
221:
222: writer.flush();
223: }
224:
225: /**
226: *
227: */
228: protected void exportPage(JRPrintPage page) throws IOException {
229: JRGridLayout layout = new JRGridLayout(JRCsvExporterNature
230: .getInstance(), page.getElements(), jasperPrint
231: .getPageWidth(), jasperPrint.getPageHeight(),
232: globalOffsetX, globalOffsetY, null //address
233: );
234:
235: JRExporterGridCell[][] grid = layout.getGrid();
236:
237: StringBuffer rowbuffer = null;
238:
239: JRPrintElement element = null;
240: String text = null;
241: boolean isFirstColumn = true;
242: for (int y = 0; y < grid.length; y++) {
243: rowbuffer = new StringBuffer();
244:
245: if (layout.isRowNotEmpty(y)) {
246: isFirstColumn = true;
247: for (int x = 0; x < grid[y].length; x++) {
248: if (grid[y][x].getWrapper() != null) {
249: element = grid[y][x].getWrapper().getElement();
250:
251: if (element instanceof JRPrintText) {
252: JRStyledText styledText = getStyledText((JRPrintText) element);
253: if (styledText == null) {
254: text = "";
255: } else {
256: text = styledText.getText();
257: }
258:
259: if (!isFirstColumn) {
260: rowbuffer.append(delimiter);
261: }
262: rowbuffer.append(prepareText(text));
263: isFirstColumn = false;
264: }
265: } else {
266: if (layout.isColNotEmpty(x)) {
267: if (!isFirstColumn) {
268: rowbuffer.append(delimiter);
269: }
270: isFirstColumn = false;
271: }
272: }
273: }
274:
275: if (rowbuffer.length() > 0) {
276: writer.write(rowbuffer.toString());
277: writer.write(recordDelimiter);
278: }
279: }
280: }
281:
282: if (progressMonitor != null) {
283: progressMonitor.afterPageExport();
284: }
285: }
286:
287: /**
288: *
289: */
290: protected JRStyledText getStyledText(JRPrintText textElement) {
291: JRStyledText styledText = null;
292:
293: String text = textElement.getText();
294: if (text != null) {
295: if (textElement.isStyledText()) {
296: try {
297: styledText = styledTextParser.parse(null, text);
298: } catch (SAXException e) {
299: //ignore if invalid styled text and treat like normal text
300: }
301: }
302:
303: if (styledText == null) {
304: styledText = new JRStyledText();
305: styledText.append(text);
306: styledText.addRun(new JRStyledText.Run(null, 0, text
307: .length()));
308: }
309: }
310:
311: return styledText;
312: }
313:
314: /**
315: *
316: */
317: protected String prepareText(String source) {
318: String str = null;
319:
320: if (source != null) {
321: boolean putQuotes = false;
322:
323: if (source.indexOf(delimiter) >= 0
324: || source.indexOf(recordDelimiter) >= 0) {
325: putQuotes = true;
326: }
327:
328: StringBuffer sbuffer = new StringBuffer();
329: StringTokenizer tkzer = new StringTokenizer(source, "\"\n",
330: true);
331: String token = null;
332: while (tkzer.hasMoreTokens()) {
333: token = tkzer.nextToken();
334: if ("\"".equals(token)) {
335: putQuotes = true;
336: sbuffer.append("\"\"");
337: } else if ("\n".equals(token)) {
338: //sbuffer.append(" ");
339: putQuotes = true;
340: sbuffer.append("\n");
341: } else {
342: sbuffer.append(token);
343: }
344: }
345:
346: str = sbuffer.toString();
347:
348: if (putQuotes) {
349: str = "\"" + str + "\"";
350: }
351: }
352:
353: return str;
354: }
355:
356: }
|