]> source.dussan.org Git - poi.git/commitdiff
bug 61021 - extract abspath from xlsb
authorTim Allison <tallison@apache.org>
Fri, 21 Apr 2017 13:02:29 +0000 (13:02 +0000)
committerTim Allison <tallison@apache.org>
Fri, 21 Apr 2017 13:02:29 +0000 (13:02 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1792198 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/xssf/binary/XSSFBParser.java
src/ooxml/java/org/apache/poi/xssf/binary/XSSFBRecordType.java
src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFBReader.java
src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestXSSFBReader.java

index 4f4fc81ff4982347fbf7fe7e8c4e356c15055040..3c52ed78ca4e37166675a589efb19b7155fbb879 100644 (file)
@@ -47,7 +47,7 @@ public abstract class XSSFBParser {
      * @param is inputStream
      * @param bitSet call {@link #handleRecord(int, byte[])} only on those records in this bitSet
      */
-    XSSFBParser(InputStream is, BitSet bitSet) {
+    protected XSSFBParser(InputStream is, BitSet bitSet) {
         this.is = new LittleEndianInputStream(is);
         records = bitSet;
     }
index 35465043067f00f5ff020738bd0264d07caa64b0..aa417a46d1615a8714f43c36467980d9fc7b2f24 100644 (file)
@@ -74,6 +74,8 @@ public enum XSSFBRecordType {
 
     BrtBundleSh(156), //defines worksheet in wb part
 
+    BrtAbsPath15(2071), //Excel 2013 path where the file was stored in wbpart
+
     //TODO -- implement these as needed
     //BrtFileVersion(128), //file version
     //BrtWbProp(153), //Workbook prop contains 1904/1900-date based bit
index 825422936e1555d93803358670845f29308ca357..0606ecec482d510b76a0e4e02be62d5be01f4a3d 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.xssf.eventusermodel;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.BitSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -31,6 +32,7 @@ import org.apache.poi.openxml4j.opc.PackagePartName;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -62,6 +64,26 @@ public class XSSFBReader extends XSSFReader {
         super(pkg);
     }
 
+    /**
+     * In Excel 2013, the absolute path where the file was last saved may be stored in
+     * the {@link XSSFBRecordType#BrtAbsPath15} record.  The equivalent in ooxml is
+     * &lt;x15ac:absPath&gt;.
+     *
+     * @return absolute path or <code>null</code> if it could not be found.
+     * @throws IOException when there's a problem with the workbook part's stream
+     */
+    public String getAbsPathMetadata() throws IOException {
+        InputStream is = null;
+        try {
+            is = workbookPart.getInputStream();
+            PathExtractor p = new PathExtractor(workbookPart.getInputStream());
+            p.parse();
+            return p.getPath();
+        } finally {
+            IOUtils.closeQuietly(is);
+        }
+    }
+
     /**
      * Returns an Iterator which will let you get at all the
      *  different Sheets in turn.
@@ -137,6 +159,36 @@ public class XSSFBReader extends XSSFReader {
 
     }
 
+
+    private static class PathExtractor extends XSSFBParser {
+        private static BitSet RECORDS = new BitSet();
+        static {
+            RECORDS.set(XSSFBRecordType.BrtAbsPath15.getId());
+        }
+        private String path = null;
+        public PathExtractor(InputStream is) {
+            super(is, RECORDS);
+        }
+
+        @Override
+        public void handleRecord(int recordType, byte[] data) throws XSSFBParseException {
+            if (recordType != XSSFBRecordType.BrtAbsPath15.getId()) {
+                return;
+            }
+            StringBuilder sb = new StringBuilder();
+            XSSFBUtils.readXLWideString(data, 0, sb);
+            path = sb.toString();
+        }
+
+        /**
+         *
+         * @return the path if found, otherwise <code>null</code>
+         */
+        String getPath() {
+            return path;
+        }
+    }
+
     private static class SheetRefLoader extends XSSFBParser {
         List<XSSFSheetRef> sheets = new LinkedList<XSSFSheetRef>();
 
index 6ea5332760c79bf928987bf4605311fdd30c8280..4c12af47082c8fdb8a93d4712722560df15a61af 100644 (file)
@@ -118,6 +118,13 @@ public class TestXSSFBReader {
 
     }
 
+    @Test
+    public void testAbsPath() throws Exception {
+        OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream("testVarious.xlsb"));
+        XSSFBReader r = new XSSFBReader(pkg);
+        assertEquals("C:\\Users\\tallison\\Desktop\\working\\xlsb\\", r.getAbsPathMetadata());
+    }
+
     private List<String> getSheets(String testFileName) throws Exception {
         OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream(testFileName));
         List<String> sheetTexts = new ArrayList<String>();