001: /* ============================================================================
002: * GNU Lesser General Public License
003: * ============================================================================
004: *
005: * Copyright (C) 2001-2007 JasperSoft Corporation http://www.jaspersoft.com
006: *
007: * This class is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This class is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this class; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * JasperSoft Corporation
022: * 303 Second Street, Suite 450 North
023: * San Francisco, CA 94107
024: * http://www.jaspersoft.com
025: *
026: *
027: *
028: * JRTxtExporter.java
029: *
030: * Created on 16 aprile 2004, 10.27
031: *
032: */
033:
034: package it.businesslogic.ireport.export;
035:
036: import java.io.File;
037: import java.io.FileOutputStream;
038: import java.io.IOException;
039: import java.io.OutputStream;
040: import java.io.OutputStreamWriter;
041: import java.io.StringWriter;
042: import java.io.Writer;
043: import java.util.ArrayList;
044: import java.util.Collection;
045: import java.util.Collections;
046: import java.util.Iterator;
047: import java.util.List;
048: import java.util.StringTokenizer;
049: import java.util.Vector;
050:
051: import net.sf.jasperreports.engine.export.*;
052: import net.sf.jasperreports.engine.JRAbstractExporter;
053: import net.sf.jasperreports.engine.JRException;
054: import net.sf.jasperreports.engine.JRExporterParameter;
055: import net.sf.jasperreports.engine.JRPrintElement;
056: import net.sf.jasperreports.engine.JRPrintPage;
057: import net.sf.jasperreports.engine.JRPrintText;
058:
059: /**
060: *
061: * @author giulio toffoli
062: *
063: * This is a really simple exporter with many assumptions on report.
064: * The report page is divided in a grid of 10 pixel x 10 pixel. In each of this
065: * pixels there is a char.
066: * Elements must be inserted into this grid (so elements must have coords and dims
067: * that are multiple of 10px).
068: *
069: */
070: public class JRTxtExporter extends JRAbstractExporter {
071:
072: /** Creates a new instance of JRPdfExporter */
073: public JRTxtExporter() {
074:
075: }
076:
077: int PAGE_ROWS = 61;
078: int PAGE_COLUMNS = 255;
079: int CHAR_UNIT_H = 10;
080: int CHAR_UNIT_V = 20;
081: boolean ADD_FORM_FEED = true;
082:
083: /**
084: *
085: */
086: protected String delimiter = null;
087:
088: /**
089: *
090: */
091: protected Writer writer = null;
092: protected JRExportProgressMonitor progressMonitor = null;
093:
094: /**
095: *
096: */
097: public void exportReport() throws JRException {
098: progressMonitor = (JRExportProgressMonitor) parameters
099: .get(JRExporterParameter.PROGRESS_MONITOR);
100:
101: /* */
102: setInput();
103:
104: /* */
105: setPageRange();
106:
107: String encoding = (String) parameters
108: .get(JRExporterParameter.CHARACTER_ENCODING);
109: if (encoding == null) {
110: encoding = "ISO-8859-1";
111: }
112:
113: String page_rows = (String) parameters
114: .get(JRTxtExporterParameter.PAGE_ROWS);
115: if (page_rows != null) {
116: PAGE_ROWS = Integer.parseInt(page_rows);
117: ;
118: } else {
119: PAGE_ROWS = this .jasperPrint.getPageHeight() / 20;
120: }
121:
122: String page_cols = (String) parameters
123: .get(JRTxtExporterParameter.PAGE_COLUMNS);
124: if (page_cols != null) {
125: PAGE_COLUMNS = Integer.parseInt(page_cols);
126: } else {
127: PAGE_COLUMNS = this .jasperPrint.getPageWidth()
128: / this .CHAR_UNIT_H;
129: }
130:
131: Object add_form_feed = parameters
132: .get(JRTxtExporterParameter.ADD_FORM_FEED);
133: if (add_form_feed != null) {
134:
135: ADD_FORM_FEED = (add_form_feed + "").equals("true");
136: } else {
137: ADD_FORM_FEED = true;
138: }
139:
140: delimiter = ",";
141:
142: StringBuffer sb = (StringBuffer) parameters
143: .get(JRXmlExporterParameter.OUTPUT_STRING_BUFFER);
144: if (sb != null) {
145: try {
146: writer = new StringWriter();
147: exportReportToWriter();
148: sb.append(writer.toString());
149: } catch (IOException e) {
150: throw new JRException(
151: "Error writing to StringBuffer writer : "
152: + jasperPrint.getName(), e);
153: } finally {
154: if (writer != null) {
155: try {
156: writer.close();
157: } catch (IOException e) {
158: }
159: }
160: }
161: } else {
162: writer = (Writer) parameters
163: .get(JRExporterParameter.OUTPUT_WRITER);
164: if (writer != null) {
165: try {
166: exportReportToWriter();
167: } catch (IOException e) {
168: throw new JRException("Error writing to writer : "
169: + jasperPrint.getName(), e);
170: }
171: } else {
172: OutputStream os = (OutputStream) parameters
173: .get(JRExporterParameter.OUTPUT_STREAM);
174: if (os != null) {
175: try {
176: writer = new OutputStreamWriter(os, encoding);
177: exportReportToWriter();
178: } catch (IOException e) {
179: throw new JRException(
180: "Error writing to OutputStream writer : "
181: + jasperPrint.getName(), e);
182: }
183: } else {
184: File destFile = (File) parameters
185: .get(JRExporterParameter.OUTPUT_FILE);
186: if (destFile == null) {
187: String fileName = (String) parameters
188: .get(JRExporterParameter.OUTPUT_FILE_NAME);
189: if (fileName != null) {
190: destFile = new File(fileName);
191: } else {
192: throw new JRException(
193: "No output specified for the exporter.");
194: }
195: }
196:
197: try {
198: os = new FileOutputStream(destFile);
199: writer = new OutputStreamWriter(os, encoding);
200: exportReportToWriter();
201: } catch (IOException e) {
202: throw new JRException(
203: "Error writing to file writer : "
204: + jasperPrint.getName(), e);
205: } finally {
206: if (writer != null) {
207: try {
208: writer.close();
209: } catch (IOException e) {
210: }
211: }
212: }
213: }
214: }
215: }
216: }
217:
218: /**
219: *
220: */
221: protected void exportReportToWriter() throws JRException,
222: IOException {
223: List pages = jasperPrint.getPages();
224: if (pages != null && pages.size() > 0) {
225: JRPrintPage page = null;
226:
227: for (int i = startPageIndex; i <= endPageIndex; i++) {
228: if (Thread.currentThread().isInterrupted()) {
229: throw new JRException("Current thread interrupted.");
230: }
231:
232: page = (JRPrintPage) pages.get(i);
233:
234: /* */
235: exportPage(page);
236: }
237: }
238:
239: writer.flush();
240: }
241:
242: /**
243: *
244: */
245: protected void exportPage(JRPrintPage page) throws JRException,
246: IOException {
247: Vector lines = layoutGrid(page);
248:
249: int y = 0;
250: for (y = 0; y < lines.size(); y++) {
251: String s = ("" + lines.elementAt(y));
252: while (s.endsWith(" ")) {
253: s = s.substring(0, s.length() - 1);
254: }
255: writer.write(s);
256: writer.write("\n");
257: }
258:
259: while (y < PAGE_ROWS) {
260: writer.write("\n");
261: y++;
262: }
263: if (ADD_FORM_FEED) {
264: writer.write("\f");
265: }
266:
267: if (progressMonitor != null) {
268: progressMonitor.afterPageExport();
269: }
270: }
271:
272: /**
273: *
274: */
275: protected Vector layoutGrid(JRPrintPage page) {
276: Vector v_lines = new Vector();
277:
278: String void_line = "";
279: for (int i = 0; i < PAGE_COLUMNS; ++i) {
280: void_line += " ";
281: }
282:
283: for (int i = 0; i < PAGE_ROWS; ++i) {
284: v_lines.add(void_line += " ");
285: }
286:
287: List yCuts = yCuts = new ArrayList();
288: yCuts.add(new Integer(0));
289: yCuts.add(new Integer(jasperPrint.getPageHeight()));
290:
291: Integer y = null;
292:
293: Collection elems = page.getElements();
294: for (Iterator it = elems.iterator(); it.hasNext();) {
295: JRPrintElement element = ((JRPrintElement) it.next());
296:
297: if (element instanceof JRPrintText) {
298: y = new Integer(element.getY());
299: if (!yCuts.contains(y)) {
300: yCuts.add(y);
301: }
302: y = new Integer(element.getY() + element.getHeight());
303: if (!yCuts.contains(y)) {
304: yCuts.add(y);
305: }
306: }
307: }
308:
309: Collections.sort(yCuts);
310: int yCellCount = yCuts.size() - 1;
311:
312: int real_line_num = 0;
313:
314: for (int j = 0; j < yCellCount; j++) {
315: if (v_lines.size() <= real_line_num) {
316: v_lines.add(new String(void_line));
317: }
318:
319: int actual_cut = ((Integer) (yCuts.get(j))).intValue();
320:
321: int lines_used = 1;
322: // Look for all elements that have Y = actual cut
323: for (Iterator it = elems.iterator(); it.hasNext();) {
324: JRPrintElement element = ((JRPrintElement) it.next());
325:
326: if (element instanceof JRPrintText) {
327: JRPrintText pt = (JRPrintText) element;
328:
329: if (pt.getY() == actual_cut) {
330: // 1. take starting char...
331: int start_at = pt.getX() / CHAR_UNIT_H;
332: int len = pt.getWidth() / CHAR_UNIT_H;
333:
334: String str = pt.getText();
335: int line_height = 0;
336: if (pt.getHeight() <= CHAR_UNIT_V) // Single line object
337: {
338:
339: if (str.length() > len) {
340: str = str.substring(0, len);
341: }
342:
343: if (pt.getY() / CHAR_UNIT_V > real_line_num) {
344: real_line_num = pt.getY() / CHAR_UNIT_V;
345: }
346: if (v_lines.size() <= real_line_num) {
347: v_lines.add(new String(void_line));
348: }
349: String line = (String) v_lines
350: .elementAt(real_line_num);
351:
352: line = replaceLineRegion(line, start_at,
353: len, str, pt.getTextAlignment());
354: v_lines.setElementAt(line, real_line_num);
355: } else // is a multiline...
356: {
357: int max_field_lines = 1;
358:
359: //Vector field_lines = getFieldLines(line_height + " " + pt.getHeight() + " " + max_field_lines + str,len);
360: Vector field_lines = getFieldLines(str, len);
361:
362: // For each line, write the right text...
363: int nl = 0;
364: for (nl = 0; nl < field_lines.size(); nl++) {
365: String text = (String) field_lines
366: .elementAt(nl);
367: //text = text.replace(' ','*');
368:
369: //text = field_lines.size()+ " " +text;
370: while (v_lines.size() <= (real_line_num + nl))
371: v_lines.add(new String(void_line));
372:
373: String line = (String) v_lines
374: .elementAt(real_line_num + nl);
375: line = replaceLineRegion(line,
376: start_at, len, text, pt
377: .getTextAlignment());
378: v_lines.setElementAt(line,
379: real_line_num + nl);
380: if (nl > lines_used)
381: lines_used = nl;
382: }
383:
384: }
385: }
386:
387: //isRowUsed[y1] = true;
388: //isColUsed[x1] = true;
389: }
390: }
391:
392: real_line_num += lines_used;
393: }
394:
395: return v_lines;
396: }
397:
398: protected String replaceLineRegion(String line, int start_at,
399: int len, String str, byte alignment) {
400: int side = 0;
401: if (alignment == net.sf.jasperreports.engine.JRAlignment.HORIZONTAL_ALIGN_CENTER) {
402: side = len - str.length();
403: if (side > 0) {
404: side = side / 2;
405: }
406: }
407:
408: for (int k = 0; k < side; ++k) {
409: str = " " + str;
410: }
411:
412: if (alignment == net.sf.jasperreports.engine.JRAlignment.HORIZONTAL_ALIGN_RIGHT) {
413: while (str.length() < len)
414: str = " " + str;
415: }
416:
417: while (str.length() < len)
418: str += " ";
419:
420: return line.substring(0, start_at) + str
421: + line.substring(start_at + len);
422: }
423:
424: public Vector getFieldLines(String str, int row_len) {
425: Vector lines = new Vector();
426:
427: StringTokenizer st = new StringTokenizer(str, "\n", false);
428: while (st.hasMoreTokens()) {
429: String token = st.nextToken();
430: while (token.length() > row_len) {
431: // Find the last space before character row_len....
432: String tmp_line = token.substring(0, row_len);
433: int li = tmp_line.lastIndexOf(' ');
434: if (token.charAt(row_len) == ' ') {
435: lines.addElement(tmp_line);
436: token = token.substring(row_len).trim();
437: } else if (li == -1) {
438: lines.addElement(tmp_line);
439: token = token.substring(row_len).trim();
440: } else {
441: tmp_line = token.substring(0, li);
442: lines.addElement(tmp_line);
443: token = token.substring(li + 1).trim();
444: }
445:
446: }
447: if (token.trim().length() > 0) {
448: if (lines.size() == 0)
449: lines.addElement(token);
450: else
451: lines.addElement(token.trim());
452: }
453: }
454: //lines.addElement("" +row_len);
455:
456: return lines;
457: }
458: }
|