1
54
55
60 package org.apache.poi.hssf.usermodel;
61
62 import org.apache.poi.util.POILogFactory;
63 import org.apache.poi.hssf.model.Sheet;
64 import org.apache.poi.hssf.model.Workbook;
65 import org.apache.poi.hssf.record.*;
66 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
67 import org.apache.poi.poifs.filesystem.Entry;
68 import org.apache.poi.poifs.filesystem.DirectoryEntry;
69 import org.apache.poi.poifs.filesystem.DocumentEntry;
70 import org.apache.poi.poifs.filesystem.DocumentInputStream;
71 import org.apache.poi.util.POILogger;
72
73 import java.io.ByteArrayInputStream;
74 import java.io.IOException;
75 import java.io.InputStream;
76 import java.io.OutputStream;
77 import java.util.ArrayList;
78 import java.util.List;
79 import java.util.Iterator;
80
81
93
94 public class HSSFWorkbook
95 extends java.lang.java.lang.Objectvate static final int DEBUG = POILogger.DEBUG;
96
97
103
104 public final static int INITIAL_CAPACITY = 3;
105
106
109
110 private Workbook workbook;
111
112
115
116 private ArrayList sheets;
117
118
121
122 private ArrayList names;
123
124
128 private boolean preserveNodes;
129
130
134 private POIFSFileSystem poifs;
135
136 private static POILogger log = POILogFactory.getLogger(HSSFWorkbook.class);
137
138
142
143 public HSSFWorkbook()
144 {
145 workbook = Workbook.createWorkbook();
146 sheets = new ArrayList(INITIAL_CAPACITY);
147 names = new ArrayList(INITIAL_CAPACITY);
148 }
149
150 public HSSFWorkbook(POIFSFileSystem fs) throws IOException {
151 this(fs,true);
152 }
153
154
165
166 public HSSFWorkbook(POIFSFileSystem fs, boolean preserveNodes)
167 throws IOException
168 {
169 this.preserveNodes = preserveNodes;
170
171 if (preserveNodes) {
172 this.poifs = fs;
173 }
174
175 sheets = new ArrayList(INITIAL_CAPACITY);
176 names = new ArrayList(INITIAL_CAPACITY);
177
178 InputStream stream = fs.createDocumentInputStream("Workbook");
179 List records = RecordFactory.createRecords(stream);
180
181 workbook = Workbook.createWorkbook(records);
182 setPropertiesFromWorkbook(workbook);
183 int recOffset = workbook.getNumRecords();
184 int sheetNum = 0;
185
186 while (recOffset < records.size())
187 {
188 Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset );
189
190 recOffset = sheet.getEofLoc()+1;
191 sheet.convertLabelRecords(
192 workbook);
193 HSSFSheet hsheet = new HSSFSheet(workbook, sheet);
194
195 sheets.add(hsheet);
196
197
198 }
199
200 for (int i = 0 ; i < workbook.getNumNames() ; ++i){
201 HSSFName name = new HSSFName(workbook, workbook.getNameRecord(i));
202 names.add(name);
203 }
204 }
205
206 public HSSFWorkbook(InputStream s) throws IOException {
207 this(s,true);
208 }
209
210
222
223 public HSSFWorkbook(InputStream s, boolean preserveNodes)
224 throws IOException
225 {
226 this(new POIFSFileSystem(s), preserveNodes);
227 }
228
229
232
233 private void setPropertiesFromWorkbook(Workbook book)
234 {
235 this.workbook = book;
236
237
238 }
239
240 public final static byte ENCODING_COMPRESSED_UNICODE = 0;
241 public final static byte ENCODING_UTF_16 = 1;
242
243
248
249 public void setSheetName(int sheet, String name)
250 {
251 workbook.setSheetName( sheet, name, ENCODING_COMPRESSED_UNICODE );
252 }
253
254 public void setSheetName( int sheet, String name, short encoding )
255 {
256 if (sheet > (sheets.size() - 1))
257 {
258 throw new RuntimeException("Sheet out of bounds");
259 }
260
261 switch ( encoding ) {
262 case ENCODING_COMPRESSED_UNICODE:
263 case ENCODING_UTF_16:
264 break;
265
266 default:
267
268 throw new RuntimeException( "Unsupported encoding" );
269 }
270
271 workbook.setSheetName( sheet, name, encoding );
272 }
273
274
279
280 public String getSheetName(int sheet)
281 {
282 if (sheet > (sheets.size() - 1))
283 {
284 throw new RuntimeException("Sheet out of bounds");
285 }
286 return workbook.getSheetName(sheet);
287 }
288
289
294
295
299 public int getSheetIndex(String name)
300 {
301 int retval = workbook.getSheetIndex(name);
302
303 return retval;
304 }
305
306
312
313 public HSSFSheet createSheet()
314 {
315
316
317
318 HSSFSheet sheet = new HSSFSheet(workbook);
319
320 sheets.add(sheet);
321 workbook.setSheetName(sheets.size() - 1,
322 "Sheet" + (sheets.size() - 1));
323 WindowTwoRecord windowTwo = (WindowTwoRecord) sheet.getSheet().findFirstRecordBySid(WindowTwoRecord.sid);
324 windowTwo.setSelected(sheets.size() == 1);
325 windowTwo.setPaged(sheets.size() == 1);
326 return sheet;
327 }
328
329
334
335 public HSSFSheet cloneSheet(int sheetNum) {
336 HSSFSheet srcSheet = (HSSFSheet)sheets.get(sheetNum);
337 String srcName = workbook.getSheetName(sheetNum);
338 if (srcSheet != null) {
339 HSSFSheet clonedSheet = srcSheet.cloneSheet(workbook);
340 WindowTwoRecord windowTwo = (WindowTwoRecord) clonedSheet.getSheet().findFirstRecordBySid(WindowTwoRecord.sid);
341 windowTwo.setSelected(sheets.size() == 1);
342 windowTwo.setPaged(sheets.size() == 1);
343
344 sheets.add(clonedSheet);
345 workbook.setSheetName(sheets.size()-1, srcName+"[1]");
346 return clonedSheet;
347 }
348 return null;
349 }
350
351
358
359 public HSSFSheet createSheet(String sheetname)
360 {
361
362
363
364 HSSFSheet sheet = new HSSFSheet(workbook);
365
366 sheets.add(sheet);
367 workbook.setSheetName(sheets.size() - 1, sheetname);
368 WindowTwoRecord windowTwo = (WindowTwoRecord) sheet.getSheet().findFirstRecordBySid(WindowTwoRecord.sid);
369 windowTwo.setSelected(sheets.size() == 1);
370 windowTwo.setPaged(sheets.size() == 1);
371 return sheet;
372 }
373
374
378
379 public int getNumberOfSheets()
380 {
381 return sheets.size();
382 }
383
384
389
390 public HSSFSheet getSheetAt(int index)
391 {
392 return (HSSFSheet) sheets.get(index);
393 }
394
395
400
401 public HSSFSheet getSheet(String name)
402 {
403 HSSFSheet retval = null;
404
405 for (int k = 0; k < sheets.size(); k++)
406 {
407 String sheetname = workbook.getSheetName(k);
408
409 if (sheetname.equals(name))
410 {
411 retval = (HSSFSheet) sheets.get(k);
412 }
413 }
414 return retval;
415 }
416
417
421
422 public void removeSheetAt(int index)
423 {
424 sheets.remove(index);
425 workbook.removeSheet(index);
426 }
427
428
433
434 public void setBackupFlag(boolean backupValue)
435 {
436 BackupRecord backupRecord = workbook.getBackupRecord();
437
438 backupRecord.setBackup(backupValue ? (short) 1
439 : (short) 0);
440 }
441
442
447
448 public boolean getBackupFlag()
449 {
450 BackupRecord backupRecord = workbook.getBackupRecord();
451
452 return (backupRecord.getBackup() == 0) ? false
453 : true;
454 }
455
456
460
461 public HSSFFont createFont()
462 {
463 FontRecord font = workbook.createNewFont();
464 short fontindex = (short) (getNumberOfFonts() - 1);
465
466 if (fontindex > 3)
467 {
468 fontindex++;
469 }
470 HSSFFont retval = new HSSFFont(fontindex, font);
471
472 return retval;
473 }
474
475
479
480 public short getNumberOfFonts()
481 {
482 return (short) workbook.getNumberOfFontRecords();
483 }
484
485
490
491 public HSSFFont getFontAt(short idx)
492 {
493 FontRecord font = workbook.getFontRecordAt(idx);
494 HSSFFont retval = new HSSFFont(idx, font);
495
496 return retval;
497 }
498
499
503
504 public HSSFCellStyle createCellStyle()
505 {
506 ExtendedFormatRecord xfr = workbook.createCellXF();
507 short index = (short) (getNumCellStyles() - 1);
508 HSSFCellStyle style = new HSSFCellStyle(index, xfr);
509
510 return style;
511 }
512
513
517
518 public short getNumCellStyles()
519 {
520 return (short) workbook.getNumExFormats();
521 }
522
523
528
529 public HSSFCellStyle getCellStyleAt(short idx)
530 {
531 ExtendedFormatRecord xfr = workbook.getExFormatAt(idx);
532 HSSFCellStyle style = new HSSFCellStyle(idx, xfr);
533
534 return style;
535 }
536
537
547
548 public void write(OutputStream stream)
549 throws IOException
550 {
551 byte[] bytes = getBytes();
552 POIFSFileSystem fs = new POIFSFileSystem();
553
554 fs.createDocument(new ByteArrayInputStream(bytes), "Workbook");
555
556 if (preserveNodes) {
557 List excepts = new ArrayList(1);
558 excepts.add("Workbook");
559 copyNodes(this.poifs,fs,excepts);
560 }
561 fs.writeFilesystem(stream);
562
563 }
564
565
576
577 public byte[] getBytes()
578 {
579 log.log(DEBUG, "HSSFWorkbook.getBytes()");
580 int wbsize = workbook.getSize();
581
582
583
584 int totalsize = wbsize;
585
586 for (int k = 0; k < sheets.size(); k++)
587 {
588 workbook.setSheetBof(k, totalsize);
589
590
591 totalsize += ((HSSFSheet) sheets.get(k)).getSheet().getSize();
592 }
593
597 byte[] retval = new byte[totalsize];
598 int pos = workbook.serialize(0, retval);
599
600
601 for (int k = 0; k < sheets.size(); k++)
602 {
603
604
605
606 pos += ((HSSFSheet) sheets.get(k)).getSheet().serialize(pos,
607 retval);
608 }
609
613 return retval;
614 }
615
616 public int addSSTString(String string)
617 {
618 return workbook.addSSTString(string);
619 }
620
621 public String getSSTString(int index)
622 {
623 return workbook.getSSTString(index);
624 }
625
626 Workbook getWorkbook()
627 {
628 return workbook;
629 }
630
631
634 public int getNumberOfNames(){
635 int result = names.size();
636 return result;
637 }
638
639
643 public HSSFName getNameAt(int index){
644 HSSFName result = (HSSFName) names.get(index);
645
646 return result;
647 }
648
649
653 public String getNameName(int index){
654 String result = getNameAt(index).getNameName();
655
656 return result;
657 }
658
659
660
663 public HSSFName createName(){
664 NameRecord nameRecord = workbook.createName();
665
666 HSSFName newName = new HSSFName(workbook, nameRecord);
667
668 names.add(newName);
669
670 return newName;
671 }
672
673
677 public int getNameIndex(String name)
678 {
679 int retval = -1;
680
681 for (int k = 0; k < names.size(); k++)
682 {
683 String nameName = getNameName(k);
684
685 if (nameName.equals(name))
686 {
687 retval = k;
688 break;
689 }
690 }
691 return retval;
692 }
693
694
695
698 public void removeName(int index){
699 names.remove(index);
700 workbook.removeName(index);
701 }
702
703
709 public HSSFDataFormat createDataFormat() {
710 return new HSSFDataFormat(workbook);
711 }
712
713
716 public void removeName(String name){
717 int index = getNameIndex(name);
718
719 removeName(index);
720
721 }
722
723
729 private void copyNodes(POIFSFileSystem source, POIFSFileSystem target,
730 List excepts) throws IOException {
731
732
733 DirectoryEntry root = source.getRoot();
734 DirectoryEntry newRoot = target.getRoot();
735
736 Iterator entries = root.getEntries();
737
738 while (entries.hasNext()) {
739 Entry entry = (Entry)entries.next();
740 if (!isInList(entry.getName(), excepts)) {
741 copyNodeRecursively(entry,newRoot);
742 }
743 }
744 }
745
746 private boolean isInList(String entry, List list) {
747 for (int k = 0; k < list.size(); k++) {
748 if (((String)list.get(k)).equals(entry)) {
749 return true;
750 }
751 }
752 return false;
753 }
754
755 private void copyNodeRecursively(Entry entry, DirectoryEntry target)
756 throws IOException {
757
758
759 DirectoryEntry newTarget = null;
760 if (entry.isDirectoryEntry()) {
761 newTarget = target.createDirectory(entry.getName());
762 Iterator entries = ((DirectoryEntry)entry).getEntries();
763
764 while (entries.hasNext()) {
765 copyNodeRecursively((Entry)entries.next(),newTarget);
766 }
767 } else {
768 DocumentEntry dentry = (DocumentEntry)entry;
769 DocumentInputStream dstream = new DocumentInputStream(dentry);
770 target.createDocument(dentry.getName(),dstream);
771 dstream.close();
772 }
773 }
774
775 }
776