bug 61021 - extract abspath from xlsb

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1792198 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Tim Allison 2017-04-21 13:02:29 +00:00
parent f5b90cbbee
commit c2dc3ad585
4 changed files with 62 additions and 1 deletions

View 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;
}

View 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

View 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
* <x15ac:absPath>.
*
* @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>();

View 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>();