@@ -113,7 +113,6 @@ Licensed to the Apache Software Foundation (ASF) under one or more
113113import org .apache .poi .util .LittleEndian ;
114114import org .apache .poi .util .LittleEndianByteArrayInputStream ;
115115import org .apache .poi .util .LittleEndianByteArrayOutputStream ;
116- import org .apache .poi .util .Removal ;
117116
118117/**
119118 * High level representation of a workbook. This is the first object most users
@@ -205,6 +204,12 @@ public final class HSSFWorkbook extends POIDocument implements Workbook {
205204 */
206205 private final UDFFinder _udfFinder = new IndexedUDFFinder (AggregatingUDFFinder .DEFAULT );
207206
207+ /**
208+ * The password needed to decrypt this workbook.
209+ * @since 6.0.0
210+ */
211+ private char [] passwordChars ;
212+
208213 public static HSSFWorkbook create (InternalWorkbook book ) {
209214 return new HSSFWorkbook (book );
210215 }
@@ -325,7 +330,7 @@ public static String getWorkbookDirEntryName(DirectoryNode directory) {
325330 * low level models. If you're reading in a workbook...start here.
326331 *
327332 * @param directory the POI filesystem directory to process from
328- * @param fs the POI filesystem that contains the Workbook stream.
333+ * @param fs the POI filesystem that contains the Workbook stream (ignored) .
329334 * @param preserveNodes whether to preserve other nodes, such as
330335 * macros. This takes more memory, so only say yes if you
331336 * need to. If set, will store all of the POIFSFileSystem
@@ -334,6 +339,7 @@ public static String getWorkbookDirEntryName(DirectoryNode directory) {
334339 * @throws IllegalStateException a number of runtime exceptions can be thrown, especially if there are problems with the
335340 * input format
336341 * @see POIFSFileSystem
342+ * @deprecated the <code>fs</code> param is ignored - use the constructor that omits it
337343 */
338344 public HSSFWorkbook (DirectoryNode directory , POIFSFileSystem fs , boolean preserveNodes )
339345 throws IOException {
@@ -357,10 +363,33 @@ public HSSFWorkbook(DirectoryNode directory, POIFSFileSystem fs, boolean preserv
357363 */
358364 public HSSFWorkbook (DirectoryNode directory , boolean preserveNodes )
359365 throws IOException {
366+ this (directory , preserveNodes , null );
367+ }
368+
369+ /**
370+ * given a POI POIFSFileSystem object, and a specific directory
371+ * within it, read in its Workbook and populate the high and
372+ * low level models. If you're reading in a workbook...start here.
373+ *
374+ * @param directory the POI filesystem directory to process from
375+ * @param preserveNodes whether to preserve other nodes, such as
376+ * macros. This takes more memory, so only say yes if you
377+ * need to. If set, will store all of the POIFSFileSystem
378+ * in memory
379+ * @param password in char array format (can be null)
380+ * @throws IOException if the stream cannot be read
381+ * @throws IllegalStateException a number of runtime exceptions can be thrown, especially if there are problems with the
382+ * input format
383+ * @see POIFSFileSystem
384+ * @since 6.0.0
385+ */
386+ public HSSFWorkbook (DirectoryNode directory , boolean preserveNodes , char [] password )
387+ throws IOException {
360388 super (directory );
361389 String workbookName = getWorkbookDirEntryName (directory );
362390
363391 this .preserveNodes = preserveNodes ;
392+ this .passwordChars = password ;
364393
365394 // If we're not preserving nodes, don't track the
366395 // POIFS any more
@@ -375,7 +404,7 @@ public HSSFWorkbook(DirectoryNode directory, boolean preserveNodes)
375404 // it happens to be spelled.
376405 InputStream stream = directory .createDocumentInputStream (workbookName );
377406
378- List <org .apache .poi .hssf .record .Record > records = RecordFactory .createRecords (stream );
407+ List <org .apache .poi .hssf .record .Record > records = RecordFactory .createRecords (stream , password );
379408
380409 workbook = InternalWorkbook .createWorkbook (records );
381410 setPropertiesFromWorkbook (workbook );
@@ -418,6 +447,24 @@ public HSSFWorkbook(InputStream s) throws IOException {
418447 this (s , true );
419448 }
420449
450+ /**
451+ * Companion to HSSFWorkbook(POIFSFileSystem), this constructs the
452+ * POI filesystem around your {@link InputStream}, including all nodes.
453+ * <p>This calls {@link #HSSFWorkbook(InputStream, boolean)} with
454+ * preserve nodes set to true.
455+ *
456+ * @throws IOException if the stream cannot be read
457+ * @throws IllegalStateException a number of runtime exceptions can be thrown, especially if there are problems with the
458+ * input format
459+ * @see #HSSFWorkbook(InputStream, boolean)
460+ * @see #HSSFWorkbook(POIFSFileSystem)
461+ * @see POIFSFileSystem
462+ * @since 6.0.0
463+ */
464+ public HSSFWorkbook (InputStream s , char [] password ) throws IOException {
465+ this (s , true , password );
466+ }
467+
421468 /**
422469 * Companion to HSSFWorkbook(POIFSFileSystem), this constructs the
423470 * POI filesystem around your {@link InputStream}.
@@ -439,9 +486,30 @@ public HSSFWorkbook(InputStream s, boolean preserveNodes)
439486 }
440487
441488 /**
442- * used internally to set the workbook properties.
489+ * Companion to HSSFWorkbook(POIFSFileSystem), this constructs the
490+ * POI filesystem around your {@link InputStream}.
491+ *
492+ * @param s the POI filesystem that contains the Workbook stream.
493+ * @param preserveNodes whether to preserve other nodes, such as
494+ * macros. This takes more memory, so only say yes if you
495+ * need to.
496+ * @param password in char array format (can be null)
497+ * @throws IOException if the stream cannot be read
498+ * @throws IllegalStateException a number of runtime exceptions can be thrown, especially if there are problems with the
499+ * input format
500+ * @see POIFSFileSystem
501+ * @see #HSSFWorkbook(POIFSFileSystem)
502+ * @since 6.0.0
443503 */
504+ @ SuppressWarnings ("resource" ) // POIFSFileSystem always closes the stream
505+ public HSSFWorkbook (InputStream s , boolean preserveNodes , char [] password )
506+ throws IOException {
507+ this (new POIFSFileSystem (s ).getRoot (), preserveNodes , password );
508+ }
444509
510+ /**
511+ * used internally to set the workbook properties.
512+ */
445513 private void setPropertiesFromWorkbook (InternalWorkbook book ) {
446514 this .workbook = book ;
447515
@@ -1480,7 +1548,6 @@ public int serialize(int offset, byte[] data) {
14801548 }
14811549 }
14821550
1483-
14841551 /**
14851552 * Method getBytes - get the bytes of just the HSSF portions of the XLS file.
14861553 * Use this to construct a POI POIFSFileSystem yourself.
@@ -1494,7 +1561,14 @@ public byte[] getBytes() {
14941561 HSSFSheet [] sheets = getSheets ();
14951562 int nSheets = sheets .length ;
14961563
1497- updateEncryptionInfo ();
1564+ String pwdString ;
1565+ if (passwordChars != null ) {
1566+ pwdString = new String (passwordChars );
1567+ } else {
1568+ // from POI 6.0.0, using Biff8EncryptionKey is discouraged
1569+ pwdString = Biff8EncryptionKey .getCurrentUserPassword ();
1570+ }
1571+ updateEncryptionInfo (pwdString );
14981572
14991573 // before getting the workbook size we must tell the sheets that
15001574 // serialization is about to occur.
@@ -2327,12 +2401,11 @@ public EncryptionInfo getEncryptionInfo() {
23272401 }
23282402
23292403
2330- private void updateEncryptionInfo () {
2404+ private void updateEncryptionInfo (String password ) {
23312405 // make sure, that we've read all the streams ...
23322406 readProperties ();
23332407 FilePassRecord fpr = (FilePassRecord ) workbook .findFirstRecordBySid (FilePassRecord .sid );
23342408
2335- String password = Biff8EncryptionKey .getCurrentUserPassword ();
23362409 WorkbookRecordList wrl = workbook .getWorkbookRecordList ();
23372410 if (password == null ) {
23382411 if (fpr != null ) {
0 commit comments