1 /*********************************************************************
2 *
3 * Copyright (C) 2002 Andrew Khan
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ***************************************************************************/
19
20 package jxl.write.biff;
21
22 import java.io.IOException;
23 import java.io.OutputStream;
24
25 import common.Logger;
26
27 import jxl.WorkbookSettings;
28 import jxl.biff.ByteData;
29
30 /**
31 * A file of excel data to be written out. All the excel data is held
32 * in memory, and when the close method is called a CompoundFile object
33 * is used to write the Biff oriented excel data in the CompoundFile
34 * format
35 */
36 public final class File
37 {
38 /**
39 * The logger
40 */
41 private static Logger logger = Logger.getLogger(File.class);
42
43 /**
44 * The data from the excel 97 file
45 */
46 private ExcelDataOutput data;
47 /**
48 * The current position within the file
49 */
50 private int pos;
51 /**
52 * The output stream
53 */
54 private OutputStream outputStream;
55 /**
56 * The initial file size
57 */
58 private int initialFileSize;
59 /**
60 * The amount to increase the growable array by
61 */
62 private int arrayGrowSize;
63 /**
64 * The workbook settings
65 */
66 private WorkbookSettings workbookSettings;
67 /**
68 * The read compound file. This will only be non-null if there are macros
69 * or other property sets of that ilk which that we should be copying
70 */
71 jxl.read.biff.CompoundFile readCompoundFile;
72
73 /**
74 * Constructor
75 *
76 * @param os the output stream
77 * @param ws the configuration settings for this workbook
78 * @param rcf the rea compound file
79 */
80 File(OutputStream os, WorkbookSettings ws, jxl.read.biff.CompoundFile rcf)
81 throws IOException
82 {
83 outputStream = os;
84 workbookSettings = ws;
85 readCompoundFile = rcf;
86 createDataOutput();
87 }
88
89 private void createDataOutput() throws IOException
90 {
91 if (workbookSettings.getUseTemporaryFileDuringWrite())
92 {
93 data = new FileDataOutput
94 (workbookSettings.getTemporaryFileDuringWriteDirectory());
95 }
96 else
97 {
98 initialFileSize = workbookSettings.getInitialFileSize();
99 arrayGrowSize = workbookSettings.getArrayGrowSize();
100
101 data = new MemoryDataOutput(initialFileSize, arrayGrowSize);
102 }
103 }
104
105 /**
106 * Closes the file. In fact, this writes out all the excel data
107 * to disk using a CompoundFile object, and then frees up all the memory
108 * allocated to the workbook
109 *
110 * @exception IOException
111 * @param cs TRUE if this should close the stream, FALSE if the application
112 * closes it
113 */
114 void close(boolean cs) throws IOException, JxlWriteException
115 {
116 CompoundFile cf = new CompoundFile(data,
117 data.getPosition(),
118 outputStream,
119 readCompoundFile);
120 cf.write();
121
122 outputStream.flush();
123 data.close();
124
125 if (cs)
126 {
127 outputStream.close();
128 }
129
130 // Cleanup the memory a bit
131 data = null;
132
133 if (!workbookSettings.getGCDisabled())
134 {
135 System.gc();
136 }
137 }
138
139 /**
140 * Adds the biff record data to the memory allocated for this File
141 *
142 * @exception IOException
143 * @param record the record to add to the excel data
144 */
145 public void write(ByteData record) throws IOException
146 {
147 byte[] bytes = record.getBytes();
148
149 data.write(bytes);
150 }
151
152 /**
153 * Gets the current position within the file
154 *
155 * @return the current position
156 */
157 int getPos() throws IOException
158 {
159 return data.getPosition();
160 }
161
162 /**
163 * Used to manually alter the contents of the written out data. This
164 * is used when cross-referencing cell records
165 *
166 * @param pos the position to alter
167 * @param newdata the data to modify
168 */
169 void setData(byte[] newdata, int pos) throws IOException
170 {
171 data.setData(newdata, pos);
172 }
173
174 /**
175 * Sets a new output file. This allows the same workbook to be
176 * written to various different output files without having to
177 * read in any templates again
178 *
179 * @param os the output stream
180 */
181 public void setOutputFile(OutputStream os) throws IOException
182 {
183 if (data != null)
184 {
185 logger.warn("Rewriting a workbook with non-empty data");
186 }
187
188 outputStream = os;
189 createDataOutput();
190 }
191 }