From 42ffb6321086948f0aa86af848beb87a6b574305 Mon Sep 17 00:00:00 2001
From: PJ Fanning
XSSFWorkbook#close()
.
+ * + * This implementation is empty but subclasses may need to implement some logic. + *
+ * + * @since 4.0.0 + * @throws IOException if an error occurs while closing. + */ + @Override + public void close() throws IOException {} } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java index 763b094f9a..6d17d57dc5 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFFactory.java @@ -27,8 +27,8 @@ import org.apache.poi.POIXMLRelation; /** * Instantiates sub-classes of POIXMLDocumentPart depending on their relationship type */ -public final class XSSFFactory extends POIXMLFactory { - private XSSFFactory() { +public class XSSFFactory extends POIXMLFactory { + protected XSSFFactory() { } private static final XSSFFactory inst = new XSSFFactory(); @@ -50,8 +50,8 @@ public final class XSSFFactory extends POIXMLFactory { */ @Override protected POIXMLDocumentPart createDocumentPart - (Class extends POIXMLDocumentPart> cls, Class>[] classes, Object[] values) - throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + (Class extends POIXMLDocumentPart> cls, Class>[] classes, Object[] values) + throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { Constructor extends POIXMLDocumentPart> constructor = cls.getDeclaredConstructor(classes); return constructor.newInstance(values); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index 6bd11e93d6..1bb256c62d 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -127,7 +127,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { * @deprecated POI 3.17 beta 1 * @see Units#DEFAULT_CHARACTER_WIDTH */ - @Removal(version="3.19") + @Removal(version="4.1") public static final float DEFAULT_CHARACTER_WIDTH = Units.DEFAULT_CHARACTER_WIDTH; /** @@ -186,7 +186,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { * TODO */ private CalculationChain calcChain; - + /** * External Links, for referencing names or cells in other workbooks. */ @@ -236,6 +236,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { private ListPackage
object,
* see http://poi.apache.org/oxml4j/.
- *
+ *
* Once you have finished working with the Workbook, you should close the package - * by calling either {@link #close()} or {@link OPCPackage#close()}, to avoid + * by calling either {@link #close()} or {@link OPCPackage#close()}, to avoid * leaving file handles open. - * + * *
Creating a XSSFWorkbook from a file-backed OPC Package has a lower memory * footprint than an InputStream backed one. * @@ -268,12 +279,13 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { */ public XSSFWorkbook(OPCPackage pkg) throws IOException { super(pkg); - + this.xssfFactory = XSSFFactory.getInstance(); + beforeDocumentRead(); - + // Build a tree of POIXMLDocumentParts, this workbook being the root - load(XSSFFactory.getInstance()); - + load(this.xssfFactory); + // some broken Workbooks miss this... setBookViewsIfMissing(); } @@ -281,7 +293,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { /** * Constructs a XSSFWorkbook object, by buffering the whole stream into memory * and then opening an {@link OPCPackage} object for it. - * + * *
Using an {@link InputStream} requires more memory than using a File, so * if a {@link File} is available then you should instead do something like *
@@ -298,29 +310,29 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
/**
* Constructs a XSSFWorkbook object from a given file.
- *
- * Once you have finished working with the Workbook, you should close
- * the package by calling {@link #close()}, to avoid leaving file
+ *
+ *
Once you have finished working with the Workbook, you should close
+ * the package by calling {@link #close()}, to avoid leaving file
* handles open.
- *
- *
Opening a XSSFWorkbook from a file has a lower memory footprint
+ *
+ *
Opening a XSSFWorkbook from a file has a lower memory footprint
* than opening from an InputStream
- *
+ *
* @param file the file to open
*/
public XSSFWorkbook(File file) throws IOException, InvalidFormatException {
this(OPCPackage.open(file));
}
-
+
/**
* Constructs a XSSFWorkbook object given a file name.
*
- *
- *
Once you have finished working with the Workbook, you should close
- * the package by calling {@link #close()}, to avoid leaving file
+ *
+ *
Once you have finished working with the Workbook, you should close
+ * the package by calling {@link #close()}, to avoid leaving file
* handles open.
- *
- *
Opening a XSSFWorkbook from a file has a lower memory footprint
+ *
+ *
Opening a XSSFWorkbook from a file has a lower memory footprint
* than opening from an InputStream
*
* @param path the file name.
@@ -328,7 +340,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
public XSSFWorkbook(String path) throws IOException {
this(openPackage(path));
}
-
+
/**
* Constructs a XSSFWorkbook object using Package Part.
* @param part package part
@@ -337,7 +349,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
public XSSFWorkbook(PackagePart part) throws IOException {
this(part.getInputStream());
}
-
+
protected void beforeDocumentRead() {
// Ensure it isn't a XLSB file, which we don't support
if (getCorePart().getContentType().equals(XSSFRelation.XLSB_BINARY_WORKBOOK.getContentType())) {
@@ -377,13 +389,13 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
}
boolean packageReadOnly = (getPackage().getPackageAccess() == PackageAccess.READ);
-
+
if (stylesSource == null) {
// Create Styles if it is missing
if (packageReadOnly) {
stylesSource = new StylesTable();
} else {
- stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, XSSFFactory.getInstance());
+ stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, this.xssfFactory);
}
}
stylesSource.setWorkbook(this);
@@ -394,10 +406,10 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
if (packageReadOnly) {
sharedStringSource = new SharedStringsTable();
} else {
- sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance());
+ sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, this.xssfFactory);
}
}
-
+
// Load individual sheets. The order of sheets is defined by the order
// of CTSheet elements in the workbook
sheets = new ArrayList<>(shIdMap.size());
@@ -405,8 +417,8 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) {
parseSheet(shIdMap, ctSheet);
}
-
- // Load the external links tables. Their order is defined by the order
+
+ // Load the external links tables. Their order is defined by the order
// of CTExternalReference elements in the workbook
externalLinks = new ArrayList<>(elIdMap.size());
if (this.workbook.isSetExternalReferences()) {
@@ -419,7 +431,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
externalLinks.add(el);
}
}
-
+
// Process the named ranges
reprocessNamedRanges();
} catch (XmlException e) {
@@ -458,8 +470,8 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
expProps.getUnderlyingProperties().setApplication(DOCUMENT_CREATOR);
- sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, XSSFFactory.getInstance());
- stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, XSSFFactory.getInstance());
+ sharedStringSource = (SharedStringsTable)createRelationship(XSSFRelation.SHARED_STRINGS, this.xssfFactory);
+ stylesSource = (StylesTable)createRelationship(XSSFRelation.STYLES, this.xssfFactory);
stylesSource.setWorkbook(this);
namedRanges = new ArrayList<>();
@@ -467,7 +479,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
sheets = new ArrayList<>();
pivotTables = new ArrayList<>();
}
-
+
private void setBookViewsIfMissing() {
if(!workbook.isSetBookViews()) {
CTBookViews bvs = workbook.addNewBookViews();
@@ -525,7 +537,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
@Override
public int addPicture(byte[] pictureData, int format) {
int imageNumber = getAllPictures().size() + 1;
- XSSFPictureData img = createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true).getDocumentPart();
+ XSSFPictureData img = createRelationship(XSSFPictureData.RELATIONS[format], this.xssfFactory, imageNumber, true).getDocumentPart();
try (OutputStream out = img.getPackagePart().getOutputStream()) {
out.write(pictureData);
} catch (IOException e){
@@ -552,7 +564,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
*/
public int addPicture(InputStream is, int format) throws IOException {
int imageNumber = getAllPictures().size() + 1;
- XSSFPictureData img = createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true).getDocumentPart();
+ XSSFPictureData img = createRelationship(XSSFPictureData.RELATIONS[format], this.xssfFactory, imageNumber, true).getDocumentPart();
try (OutputStream out = img.getPackagePart().getOutputStream()) {
IOUtils.copy(is, out);
}
@@ -574,6 +586,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
return cloneSheet(sheetNum, null);
}
+ @Override
+ public void close() throws IOException {
+ super.close();
+ sharedStringSource.close();
+ }
+
/**
* Create an XSSFSheet from an existing sheet in the XSSFWorkbook.
* The cloned sheet is a deep copy of the original but with a new given
@@ -618,14 +636,14 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
for(PackageRelationship pr : srcSheet.getPackagePart().getRelationships()) {
if (pr.getTargetMode() == TargetMode.EXTERNAL) {
clonedSheet.getPackagePart().addExternalRelationship
- (pr.getTargetURI().toASCIIString(), pr.getRelationshipType(), pr.getId());
+ (pr.getTargetURI().toASCIIString(), pr.getRelationshipType(), pr.getId());
}
}
} catch (InvalidFormatException e) {
throw new POIXMLException("Failed to clone sheet", e);
}
-
-
+
+
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
srcSheet.write(out);
try (ByteArrayInputStream bis = new ByteArrayInputStream(out.toByteArray())) {
@@ -658,7 +676,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
clonedDg.getCTDrawing().set(dg.getCTDrawing());
clonedDg = clonedSheet.createDrawingPatriarch();
-
+
// Clone drawing relations
List srcRels = srcSheet.createDrawingPatriarch().getRelationParts();
for (RelationPart rp : srcRels) {
@@ -667,7 +685,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
return clonedSheet;
}
-
+
/**
* @since 3.14-Beta1
*/
@@ -675,8 +693,8 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
PackageRelationship rel = rp.getRelationship();
if (rel.getTargetMode() == TargetMode.EXTERNAL) {
target.getPackagePart().addRelationship(
- rel.getTargetURI(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId());
- } else {
+ rel.getTargetURI(), rel.getTargetMode(), rel.getRelationshipType(), rel.getId());
+ } else {
XSSFRelation xssfRel = XSSFRelation.getInstance(rel.getRelationshipType());
if (xssfRel == null) {
// Don't copy all relations blindly, but only the ones we know about
@@ -859,12 +877,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
for(XSSFSheet sh : sheets) {
sheetNumber = (int)Math.max(sh.sheet.getSheetId() + 1, sheetNumber);
}
-
+
// Bug 57165: We also need to check that the resulting file name is not already taken
// this can happen when moving/cloning sheets
String sheetName = XSSFRelation.WORKSHEET.getFileName(sheetNumber);
for(POIXMLDocumentPart relation : getRelations()) {
- if(relation.getPackagePart() != null &&
+ if(relation.getPackagePart() != null &&
sheetName.equals(relation.getPackagePart().getPartName().getName())) {
// name is taken => try next one
sheetNumber++;
@@ -876,7 +894,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
break;
}
- RelationPart rp = createRelationship(XSSFRelation.WORKSHEET, XSSFFactory.getInstance(), sheetNumber, false);
+ RelationPart rp = createRelationship(XSSFRelation.WORKSHEET, this.xssfFactory, sheetNumber, false);
XSSFSheet wrapper = rp.getDocumentPart();
wrapper.sheet = sheet;
sheet.setId(rp.getRelationship().getId());
@@ -904,7 +922,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
sheet.setName(sheetname);
return sheet;
}
-
+
/**
* Finds a font that matches the one with the supplied attributes
*/
@@ -1194,21 +1212,21 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
public Iterator sheetIterator() {
return new SheetIterator<>();
}
-
+
/**
* Alias for {@link #sheetIterator()} to allow
* foreach loops
- *
+ *
* Note: remove() is not supported on this iterator.
* Use {@link #removeSheetAt(int)} to remove sheets instead.
- *
+ *
* @return an iterator of the sheets.
*/
@Override
public Iterator iterator() {
return sheetIterator();
}
-
+
private final class SheetIterator implements Iterator {
final private Iterator it;
@SuppressWarnings("unchecked")
@@ -1234,7 +1252,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
"Use Sheet.removeSheetAt(int) instead.");
}
}
-
+
/**
* Are we a normal workbook (.xlsx), or a
* macro enabled workbook (.xlsm)?
@@ -1258,11 +1276,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
/**
* Remove the first named range found with the given name.
- *
+ *
* Note: names of named ranges are not unique (name + sheet
* index is unique), so {@link #removeName(Name)} should
* be used if possible.
- *
+ *
* @param name the named range name to remove
*
* @throws IllegalArgumentException if no named range could be found
@@ -1373,7 +1391,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
final XSSFSheet sheet = getSheetAt(index);
sheet.onSheetDelete();
-
+
//delete the CTSheet reference from workbook.xml
workbook.getSheets().removeSheet(index);
@@ -1445,7 +1463,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
* @param index the index to validate
* @throws IllegalArgumentException if the index is out of range (index
* < 0 || index >= getNumberOfSheets()).
- */
+ */
private void validateSheetIndex(int index) {
int lastSheetIx = sheets.size() - 1;
if (index < 0 || index > lastSheetIx) {
@@ -1592,7 +1610,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
if (sheetname == null) {
throw new IllegalArgumentException( "sheetName must not be null" );
}
-
+
validateSheetIndex(sheetIndex);
String oldSheetName = getSheetName(sheetIndex);
@@ -1606,7 +1624,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
if (sheetname.equals(oldSheetName)) {
return;
}
-
+
// Check it isn't already taken
if (containsSheet(sheetname, sheetIndex )) {
throw new IllegalArgumentException( "The workbook already contains a sheet of this name" );
@@ -1643,11 +1661,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
for(int i=0; i < sheetArray.length; i++) {
sheets.get(i).sheet = sheetArray[i];
}
-
+
updateNamedRangesAfterSheetReorder(idx, pos);
updateActiveSheetAfterSheetReorder(idx, pos);
}
-
+
/**
* update sheet-scoped named ranges in this workbook after changing the sheet order
* of a sheet at oldIndex to newIndex.
@@ -1677,7 +1695,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
}
}
-
+
private void updateActiveSheetAfterSheetReorder(int oldIndex, int newIndex) {
// adjust active sheet if necessary
int active = getActiveSheetIndex();
@@ -1714,7 +1732,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
workbook.unsetDefinedNames();
}
workbook.setDefinedNames(names);
-
+
// Re-process the named ranges
reprocessNamedRanges();
} else {
@@ -1723,7 +1741,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
}
}
-
+
private void reprocessNamedRanges() {
namedRangesByName = new ArrayListValuedHashMap<>();
namedRanges = new ArrayList<>();
@@ -1757,7 +1775,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
workbook.save(out, xmlOptions);
}
}
-
+
/**
* Returns SharedStringsTable - tha cache of string for this workbook
*
@@ -1855,7 +1873,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
for(PackageRelationship rel : sheet.getPackagePart().getRelationshipsByType(XSSFRelation.PACKEMBEDDINGS.getRelation())) {
- embedds.add( sheet.getPackagePart().getRelatedPart(rel) );
+ embedds.add( sheet.getPackagePart().getRelatedPart(rel) );
}
}
return embedds;
@@ -1886,7 +1904,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
CTSheet ctSheet = sheets.get(sheetIx).sheet;
return ctSheet.getState() == STSheetState.VERY_HIDDEN;
}
-
+
@Override
public SheetVisibility getSheetVisibility(int sheetIx) {
validateSheetIndex(sheetIx);
@@ -1912,7 +1930,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
@Override
public void setSheetVisibility(int sheetIx, SheetVisibility visibility) {
validateSheetIndex(sheetIx);
-
+
final CTSheet ctSheet = sheets.get(sheetIx).sheet;
switch (visibility) {
case VISIBLE:
@@ -1928,9 +1946,9 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
throw new IllegalArgumentException("This should never happen");
}
}
-
-
-
+
+
+
/**
* Fired when a formula is deleted from this workbook,
@@ -1957,10 +1975,10 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
public CalculationChain getCalculationChain() {
return calcChain;
}
-
+
/**
* Returns the list of {@link ExternalLinksTable} object for this workbook
- *
+ *
* The external links table specifies details of named ranges etc
* that are referenced from other workbooks, along with the last seen
* values of what they point to.
@@ -1994,9 +2012,9 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
/**
- * Adds the External Link Table part and relations required to allow formulas
+ * Adds the External Link Table part and relations required to allow formulas
* referencing the specified external workbook to be added to this one. Allows
- * formulas such as "[MyOtherWorkbook.xlsx]Sheet3!$A$5" to be added to the
+ * formulas such as "[MyOtherWorkbook.xlsx]Sheet3!$A$5" to be added to the
* file, for workbooks not already linked / referenced.
*
* Note: this is not implemented and thus currently throws an Exception stating this.
@@ -2088,8 +2106,8 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
/**
- * Sets the workbook password.
- *
+ * Sets the workbook password.
+ *
* @param password if null, the password will be removed
* @param hashAlgo if null, the password will be set as XOR password (Excel 2010 and earlier)
* otherwise the given algorithm is used for calculating the hash password (Excel 2013)
@@ -2115,7 +2133,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
/**
* Sets the revisions password.
- *
+ *
* @param password if null, the password will be removed
* @param hashAlgo if null, the password will be set as XOR password (Excel 2010 and earlier)
* otherwise the given algorithm is used for calculating the hash password (Excel 2013)
@@ -2138,7 +2156,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
return validatePassword(safeGetWorkbookProtection(), password, "revisions");
}
-
+
/**
* Removes the workbook protection settings
*/
@@ -2147,7 +2165,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
workbook.unsetWorkbookProtection();
}
}
-
+
private boolean workbookProtectionPresent() {
return workbook.isSetWorkbookProtection();
}
@@ -2158,7 +2176,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
}
return workbook.getWorkbookProtection();
}
-
+
/**
*
* Returns the locator of user-defined functions.
@@ -2298,7 +2316,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
OPCPackage opc = getPackage();
OutputStream outputStream;
if (!opc.containPart(ppName)) {
- POIXMLDocumentPart relationship = createRelationship(XSSFRelation.VBA_MACROS, XSSFFactory.getInstance());
+ POIXMLDocumentPart relationship = createRelationship(XSSFRelation.VBA_MACROS, this.xssfFactory);
outputStream = relationship.getPackagePart().getOutputStream();
} else {
PackagePart part = opc.getPart(ppName);
@@ -2328,7 +2346,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
/**
* Returns the spreadsheet version (EXCLE2007) of this workbook
- *
+ *
* @return EXCEL2007 SpreadsheetVersion enum
* @since 3.14 beta 2
*/
@@ -2336,10 +2354,10 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
public SpreadsheetVersion getSpreadsheetVersion() {
return SpreadsheetVersion.EXCEL2007;
}
-
+
/**
* Returns the data table with the given name (case insensitive).
- *
+ *
* @param name the data table name (case-insensitive)
* @return The Data table in the workbook named name, or null if no table is named name.
* @since 3.15 beta 2
@@ -2359,7 +2377,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
@Override
public int addOlePackage(byte[] oleData, String label, String fileName, String command)
- throws IOException {
+ throws IOException {
// find an unused part name
OPCPackage opc = getPackage();
PackagePartName pnOLE;
@@ -2373,7 +2391,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
} while (opc.containPart(pnOLE));
PackagePart pp = opc.createPart( pnOLE, "application/vnd.openxmlformats-officedocument.oleObject" );
-
+
Ole10Native ole10 = new Ole10Native(label, fileName, command, oleData);
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(oleData.length+500)) {