diff --git a/src/ooxml/java/org/apache/poi/xssf/binary/XSSFBParser.java b/src/ooxml/java/org/apache/poi/xssf/binary/XSSFBParser.java
index 4f4fc81ff..3c52ed78c 100644
--- a/src/ooxml/java/org/apache/poi/xssf/binary/XSSFBParser.java
+++ b/src/ooxml/java/org/apache/poi/xssf/binary/XSSFBParser.java
@@ -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;
}
diff --git a/src/ooxml/java/org/apache/poi/xssf/binary/XSSFBRecordType.java b/src/ooxml/java/org/apache/poi/xssf/binary/XSSFBRecordType.java
index 354650430..aa417a46d 100644
--- a/src/ooxml/java/org/apache/poi/xssf/binary/XSSFBRecordType.java
+++ b/src/ooxml/java/org/apache/poi/xssf/binary/XSSFBRecordType.java
@@ -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
diff --git a/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFBReader.java b/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFBReader.java
index 825422936..0606ecec4 100644
--- a/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFBReader.java
+++ b/src/ooxml/java/org/apache/poi/xssf/eventusermodel/XSSFBReader.java
@@ -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
+ * <x15ac:absPath>.
+ *
+ * @return absolute path or null
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 null
+ */
+ String getPath() {
+ return path;
+ }
+ }
+
private static class SheetRefLoader extends XSSFBParser {
List sheets = new LinkedList();
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestXSSFBReader.java b/src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestXSSFBReader.java
index 6ea533276..4c12af470 100644
--- a/src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestXSSFBReader.java
+++ b/src/ooxml/testcases/org/apache/poi/xssf/eventusermodel/TestXSSFBReader.java
@@ -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 getSheets(String testFileName) throws Exception {
OPCPackage pkg = OPCPackage.open(_ssTests.openResourceAsStream(testFileName));
List sheetTexts = new ArrayList();