Lines 18-25
Link Here
|
18 |
|
18 |
|
19 |
import java.util.HashSet; |
19 |
import java.util.HashSet; |
20 |
|
20 |
|
|
|
21 |
import org.apache.poi.hssf.model.InternalWorkbook; |
21 |
import org.apache.poi.hssf.record.ExtendedFormatRecord; |
22 |
import org.apache.poi.hssf.record.ExtendedFormatRecord; |
22 |
import org.apache.poi.hssf.record.FontRecord; |
23 |
import org.apache.poi.hssf.record.FontRecord; |
|
|
24 |
import org.apache.poi.hssf.record.StyleRecord; |
23 |
import org.apache.poi.hssf.record.common.UnicodeString; |
25 |
import org.apache.poi.hssf.record.common.UnicodeString; |
24 |
import org.apache.poi.ss.usermodel.Cell; |
26 |
import org.apache.poi.ss.usermodel.Cell; |
25 |
import org.apache.poi.ss.usermodel.Row; |
27 |
import org.apache.poi.ss.usermodel.Row; |
Lines 173-192
Link Here
|
173 |
public static void optimiseCellStyles(HSSFWorkbook workbook) { |
175 |
public static void optimiseCellStyles(HSSFWorkbook workbook) { |
174 |
// Where each style has ended up, and if we need to |
176 |
// Where each style has ended up, and if we need to |
175 |
// delete the record for it. Start off with no change |
177 |
// delete the record for it. Start off with no change |
176 |
short[] newPos = new short[workbook.getWorkbook().getNumExFormats()]; |
178 |
final short off = 16; |
|
|
179 |
InternalWorkbook iwb = workbook.getWorkbook(); |
180 |
short[] newPos = new short[iwb.getNumExFormats()]; |
177 |
boolean[] isUsed = new boolean[newPos.length]; |
181 |
boolean[] isUsed = new boolean[newPos.length]; |
178 |
boolean[] zapRecords = new boolean[newPos.length]; |
182 |
boolean[] zapRecords = new boolean[newPos.length]; |
|
|
183 |
short[] oldParent = new short[newPos.length]; |
184 |
|
179 |
for(int i=0; i<newPos.length; i++) { |
185 |
for(int i=0; i<newPos.length; i++) { |
|
|
186 |
HSSFCellStyle cs, csp; |
180 |
isUsed[i] = false; |
187 |
isUsed[i] = false; |
181 |
newPos[i] = (short)i; |
188 |
newPos[i] = (short)i; |
182 |
zapRecords[i] = false; |
189 |
zapRecords[i] = false; |
|
|
190 |
|
191 |
//Preserve parent indexes. |
192 |
oldParent[i] = 0; |
193 |
cs = workbook.getCellStyleAt((short)i); |
194 |
csp = cs.getParentStyle(); |
195 |
if(csp != null) |
196 |
{ |
197 |
oldParent[i] = csp.getIndex(); |
198 |
} |
199 |
|
200 |
//User defined styles is used. |
201 |
if(cs.getUserStyleName() != null) |
202 |
{ |
203 |
isUsed[i] = true; |
204 |
} |
205 |
|
206 |
//Builtin style is used. |
207 |
StyleRecord sr = iwb.getStyleRecord(i); |
208 |
if(sr != null) |
209 |
{ |
210 |
if(sr.isBuiltin()) |
211 |
{ |
212 |
isUsed[i] = true; |
213 |
} |
214 |
} |
215 |
|
216 |
|
183 |
} |
217 |
} |
184 |
|
218 |
|
185 |
// Get each style record, so we can do deletes |
219 |
// Get each style record, so we can do deletes |
186 |
// without getting confused |
220 |
// without getting confused |
187 |
ExtendedFormatRecord[] xfrs = new ExtendedFormatRecord[newPos.length]; |
221 |
ExtendedFormatRecord[] xfrs = new ExtendedFormatRecord[newPos.length]; |
188 |
for(int i=0; i<newPos.length; i++) { |
222 |
for(int i=0; i<newPos.length; i++) { |
189 |
xfrs[i] = workbook.getWorkbook().getExFormatAt(i); |
223 |
xfrs[i] = iwb.getExFormatAt(i); |
190 |
} |
224 |
} |
191 |
|
225 |
|
192 |
// Loop over each style, seeing if it is the same |
226 |
// Loop over each style, seeing if it is the same |
Lines 194-207
Link Here
|
194 |
// later duplicate copy to the earlier one, and |
228 |
// later duplicate copy to the earlier one, and |
195 |
// mark the later one as needing deleting |
229 |
// mark the later one as needing deleting |
196 |
// Only work on user added ones, which come after 20 |
230 |
// Only work on user added ones, which come after 20 |
197 |
for(int i=21; i<newPos.length; i++) { |
231 |
for(int i=off; i<newPos.length; i++) { |
|
|
232 |
|
233 |
if(isUsed[i]) |
234 |
{ |
235 |
continue; |
236 |
} |
237 |
|
198 |
// Check this one for being a duplicate |
238 |
// Check this one for being a duplicate |
199 |
// of an earlier one |
239 |
// of an earlier one |
200 |
int earlierDuplicate = -1; |
240 |
int earlierDuplicate = -1; |
201 |
for(int j=0; j<i && earlierDuplicate == -1; j++) { |
241 |
for(int j=0; j<i; j++) { |
202 |
ExtendedFormatRecord xfCheck = workbook.getWorkbook().getExFormatAt(j); |
242 |
ExtendedFormatRecord xfCheck = iwb.getExFormatAt(j); |
203 |
if(xfCheck.equals(xfrs[i])) { |
243 |
if(xfCheck.equals(xfrs[i]) && oldParent[i] == oldParent[j]) { |
204 |
earlierDuplicate = j; |
244 |
earlierDuplicate = j; |
|
|
245 |
break; |
205 |
} |
246 |
} |
206 |
} |
247 |
} |
207 |
|
248 |
|
Lines 210-219
Link Here
|
210 |
newPos[i] = (short)earlierDuplicate; |
251 |
newPos[i] = (short)earlierDuplicate; |
211 |
zapRecords[i] = true; |
252 |
zapRecords[i] = true; |
212 |
} |
253 |
} |
213 |
// If we got a duplicate, mark the one we're keeping as used |
|
|
214 |
if(earlierDuplicate != -1) { |
215 |
isUsed[earlierDuplicate] = true; |
216 |
} |
217 |
} |
254 |
} |
218 |
|
255 |
|
219 |
// Loop over all the cells in the file, and identify any user defined |
256 |
// Loop over all the cells in the file, and identify any user defined |
Lines 224-235
Link Here
|
224 |
for (Cell cellI : row) { |
261 |
for (Cell cellI : row) { |
225 |
HSSFCell cell = (HSSFCell)cellI; |
262 |
HSSFCell cell = (HSSFCell)cellI; |
226 |
short oldXf = cell.getCellValueRecord().getXFIndex(); |
263 |
short oldXf = cell.getCellValueRecord().getXFIndex(); |
227 |
isUsed[oldXf] = true; |
264 |
isUsed[newPos[oldXf]] = true; |
|
|
265 |
isUsed[oldParent[oldXf]] = true; |
228 |
} |
266 |
} |
229 |
} |
267 |
} |
230 |
} |
268 |
} |
231 |
// Mark any that aren't used as needing zapping |
269 |
// Mark any that aren't used as needing zapping |
232 |
for (int i=21; i<isUsed.length; i++) { |
270 |
for (int i=off; i<isUsed.length; i++) { |
233 |
if (! isUsed[i]) { |
271 |
if (! isUsed[i]) { |
234 |
// Un-used style, can be removed |
272 |
// Un-used style, can be removed |
235 |
zapRecords[i] = true; |
273 |
zapRecords[i] = true; |
Lines 241-247
Link Here
|
241 |
// deletes that have occurred between |
279 |
// deletes that have occurred between |
242 |
// the start and them |
280 |
// the start and them |
243 |
// Only work on user added ones, which come after 20 |
281 |
// Only work on user added ones, which come after 20 |
244 |
for(int i=21; i<newPos.length; i++) { |
282 |
for(int i=off; i<newPos.length; i++) { |
245 |
// Find the number deleted to that |
283 |
// Find the number deleted to that |
246 |
// point, and adjust |
284 |
// point, and adjust |
247 |
short preDeletePos = newPos[i]; |
285 |
short preDeletePos = newPos[i]; |
Lines 259-273
Link Here
|
259 |
// styles we did not intend to (the ones that _were_ duplicated and not the duplicates) |
297 |
// styles we did not intend to (the ones that _were_ duplicated and not the duplicates) |
260 |
int max = newPos.length; |
298 |
int max = newPos.length; |
261 |
int removed = 0; // to adjust index after deletion |
299 |
int removed = 0; // to adjust index after deletion |
262 |
for(int i=21; i<max; i++) { |
300 |
for(int i=off; i<max; i++) { |
263 |
if(zapRecords[i + removed]) { |
301 |
if(zapRecords[i + removed]) { |
264 |
workbook.getWorkbook().removeExFormatRecord(i); |
302 |
iwb.removeExFormatRecord(i); |
|
|
303 |
StyleRecord sr = iwb.getStyleRecord(i); |
304 |
if(sr!=null) { |
305 |
iwb.getRecords().remove(sr); |
306 |
} |
265 |
i--; |
307 |
i--; |
266 |
max--; |
308 |
max--; |
267 |
removed++; |
309 |
removed++; |
268 |
} |
310 |
} |
269 |
} |
311 |
} |
270 |
|
312 |
|
|
|
313 |
|
314 |
for(int i=off; i<newPos.length; i++) { |
315 |
if(!zapRecords[i] ) { |
316 |
//Edit existing record infomation. |
317 |
|
318 |
//Change parent index. |
319 |
iwb.getExFormatAt(newPos[i]).setParentIndex(newPos[oldParent[i]]); |
320 |
|
321 |
//Delete the old record before record move the new position. |
322 |
if(newPos[i] < i) { |
323 |
|
324 |
//Delete the old record. |
325 |
StyleRecord sr = iwb.getStyleRecord(newPos[i]); |
326 |
if(sr != null) |
327 |
{ |
328 |
iwb.getRecords().remove(sr); |
329 |
} |
330 |
|
331 |
//Move style record. |
332 |
sr = iwb.getStyleRecord(i); |
333 |
if(sr!=null) { |
334 |
sr.setXFIndex(newPos[i]); |
335 |
} |
336 |
|
337 |
} |
338 |
|
339 |
|
340 |
} |
341 |
|
342 |
} |
343 |
|
344 |
|
271 |
// Finally, update the cells to point at their new extended format records |
345 |
// Finally, update the cells to point at their new extended format records |
272 |
for(int sheetNum=0; sheetNum<workbook.getNumberOfSheets(); sheetNum++) { |
346 |
for(int sheetNum=0; sheetNum<workbook.getNumberOfSheets(); sheetNum++) { |
273 |
HSSFSheet s = workbook.getSheetAt(sheetNum); |
347 |
HSSFSheet s = workbook.getSheetAt(sheetNum); |