mirror of https://github.com/apache/poi.git
More work on bug #45431 - Support for .xlsm files, sufficient for simple files to be loaded by excel without warning
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@680871 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d7f86f111f
commit
a89961ba81
|
@ -37,6 +37,7 @@
|
|||
|
||||
<!-- Don't forget to update status.xml too! -->
|
||||
<release version="3.5.1-beta2" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">45431 - Support for .xlsm files, sufficient for simple files to be loaded by excel without warning</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">New class org.apache.poi.hssf.record.RecordFormatException, which DDF uses instead of the HSSF version, and the HSSF version inherits from</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">45431 - Partial support for .xlm files. Not quite enough for excel to load them though</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45430 - Correct named range sheet reporting when no local sheet id is given in the xml</action>
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
<!-- Don't forget to update changes.xml too! -->
|
||||
<changes>
|
||||
<release version="3.5.1-beta2" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">45431 - Support for .xlsm files, sufficient for simple files to be loaded by excel without warning</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">New class org.apache.poi.hssf.record.RecordFormatException, which DDF uses instead of the HSSF version, and the HSSF version inherits from</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">45431 - Partial support for .xlm files. Not quite enough for excel to load them though</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">45430 - Correct named range sheet reporting when no local sheet id is given in the xml</action>
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.apache.poi.util;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class IOUtils
|
||||
{
|
||||
|
@ -84,4 +85,19 @@ public class IOUtils
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies all the data from the given InputStream to the
|
||||
* OutputStream. It leaves both streams open, so you
|
||||
* will still need to close them once done.
|
||||
*/
|
||||
public static void copy(InputStream inp, OutputStream out) throws IOException {
|
||||
byte[] buff = new byte[4096];
|
||||
int count;
|
||||
while( (count = inp.read(buff)) != -1 ) {
|
||||
if(count > 0) {
|
||||
out.write(buff, 0, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -117,8 +117,19 @@ public abstract class POIXMLDocument {
|
|||
* @throws InvalidFormatException
|
||||
*/
|
||||
protected PackagePart getTargetPart(PackageRelationship rel) throws InvalidFormatException {
|
||||
return getTargetPart(getPackage(), rel);
|
||||
}
|
||||
/**
|
||||
* Get the PackagePart that is the target of a relationship.
|
||||
*
|
||||
* @param rel The relationship
|
||||
* @param pkg The package to fetch from
|
||||
* @return The target part
|
||||
* @throws InvalidFormatException
|
||||
*/
|
||||
public static PackagePart getTargetPart(Package pkg, PackageRelationship rel) throws InvalidFormatException {
|
||||
PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
|
||||
PackagePart part = getPackage().getPart(relName);
|
||||
PackagePart part = pkg.getPart(relName);
|
||||
if (part == null) {
|
||||
throw new IllegalArgumentException("No part found for relationship " + rel);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
package org.apache.poi.xssf.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.poi.xssf.usermodel.XSSFActiveXData;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackagePartName;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackagingURIHelper;
|
||||
import org.openxml4j.opc.TargetMode;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTControl;
|
||||
|
||||
/**
|
||||
* A control object in XSSF, which will typically
|
||||
* have active x data associated with it.
|
||||
*/
|
||||
public class Control implements XSSFChildContainingModel {
|
||||
private CTControl control;
|
||||
private String originalId;
|
||||
private ArrayList<XSSFActiveXData> activexBins;
|
||||
|
||||
public Control(InputStream is, String originalId) throws IOException {
|
||||
readFrom(is);
|
||||
this.originalId = originalId;
|
||||
this.activexBins = new ArrayList<XSSFActiveXData>();
|
||||
}
|
||||
|
||||
public String getOriginalId() {
|
||||
return this.originalId;
|
||||
}
|
||||
|
||||
public Control() {
|
||||
this.control = CTControl.Factory.newInstance();
|
||||
}
|
||||
/**
|
||||
* For unit testing only!
|
||||
*/
|
||||
protected Control(CTControl control) {
|
||||
this.control = control;
|
||||
}
|
||||
|
||||
public void readFrom(InputStream is) throws IOException {
|
||||
try {
|
||||
CTControl doc = CTControl.Factory.parse(is);
|
||||
control = doc;
|
||||
} catch (XmlException e) {
|
||||
throw new IOException(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
XmlOptions options = new XmlOptions();
|
||||
options.setSaveOuter();
|
||||
options.setUseDefaultNamespace();
|
||||
// Requests use of whitespace for easier reading
|
||||
options.setSavePrettyPrint();
|
||||
control.save(out, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds our XSSFActiveXData children
|
||||
*/
|
||||
public void findChildren(PackagePart modelPart) throws IOException, InvalidFormatException {
|
||||
for(PackageRelationship rel : modelPart.getRelationshipsByType(XSSFWorkbook.ACTIVEX_BINS.getRelation())) {
|
||||
PackagePart binPart = XSSFWorkbook.getTargetPart(modelPart.getPackage(), rel);
|
||||
XSSFActiveXData actX = new XSSFActiveXData(binPart, rel.getId());
|
||||
activexBins.add(actX);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Writes back out our XSSFPictureData children
|
||||
*/
|
||||
public void writeChildren(PackagePart modelPart) throws IOException, InvalidFormatException {
|
||||
int binIndex = 1;
|
||||
OutputStream out;
|
||||
|
||||
for(XSSFActiveXData actX : activexBins) {
|
||||
PackagePartName binPartName = PackagingURIHelper.createPartName(XSSFWorkbook.ACTIVEX_BINS.getFileName(binIndex));
|
||||
modelPart.addRelationship(binPartName, TargetMode.INTERNAL, XSSFWorkbook.ACTIVEX_BINS.getRelation(), getOriginalId());
|
||||
PackagePart imagePart = modelPart.getPackage().createPart(binPartName, XSSFWorkbook.ACTIVEX_BINS.getContentType());
|
||||
out = imagePart.getOutputStream();
|
||||
actX.writeTo(out);
|
||||
out.close();
|
||||
binIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<XSSFActiveXData> getData() {
|
||||
return this.activexBins;
|
||||
}
|
||||
|
||||
public void addData(XSSFActiveXData activeX) {
|
||||
this.activexBins.add(activeX);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
package org.apache.poi.xssf.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.apache.poi.xssf.usermodel.XSSFPictureData;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackagePartName;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackagingURIHelper;
|
||||
import org.openxml4j.opc.TargetMode;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing;
|
||||
|
||||
/**
|
||||
* A drawing object in XSSF. May well have raw pictures
|
||||
* attached to it as children.
|
||||
*/
|
||||
public class Drawing implements XSSFChildContainingModel {
|
||||
private CTDrawing drawing;
|
||||
private String originalId;
|
||||
|
||||
/** Raw pictures attached to the drawing */
|
||||
private ArrayList<XSSFPictureData> pictures;
|
||||
|
||||
public Drawing(InputStream is, String originalId) throws IOException {
|
||||
readFrom(is);
|
||||
this.originalId = originalId;
|
||||
this.pictures = new ArrayList<XSSFPictureData>();
|
||||
}
|
||||
|
||||
public String getOriginalId() {
|
||||
return this.originalId;
|
||||
}
|
||||
|
||||
public Drawing() {
|
||||
this.drawing = CTDrawing.Factory.newInstance();
|
||||
}
|
||||
/**
|
||||
* For unit testing only!
|
||||
*/
|
||||
protected Drawing(CTDrawing drawing) {
|
||||
this.drawing = drawing;
|
||||
}
|
||||
|
||||
public void readFrom(InputStream is) throws IOException {
|
||||
try {
|
||||
CTDrawing doc = CTDrawing.Factory.parse(is);
|
||||
drawing = doc;
|
||||
} catch (XmlException e) {
|
||||
throw new IOException(e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
XmlOptions options = new XmlOptions();
|
||||
options.setSaveOuter();
|
||||
options.setUseDefaultNamespace();
|
||||
// Requests use of whitespace for easier reading
|
||||
options.setSavePrettyPrint();
|
||||
drawing.save(out, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds our XSSFPictureData children
|
||||
*/
|
||||
public void findChildren(PackagePart modelPart) throws IOException, InvalidFormatException {
|
||||
for(PackageRelationship rel : modelPart.getRelationshipsByType(XSSFWorkbook.IMAGES.getRelation())) {
|
||||
PackagePart imagePart = XSSFWorkbook.getTargetPart(modelPart.getPackage(), rel);
|
||||
XSSFPictureData pd = new XSSFPictureData(imagePart, rel.getId());
|
||||
pictures.add(pd);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Writes back out our XSSFPictureData children
|
||||
*/
|
||||
public void writeChildren(PackagePart modelPart) throws IOException, InvalidFormatException {
|
||||
int pictureIndex = 1;
|
||||
OutputStream out;
|
||||
|
||||
for(XSSFPictureData picture : pictures) {
|
||||
PackagePartName imagePartName = PackagingURIHelper.createPartName(XSSFWorkbook.IMAGES.getFileName(pictureIndex));
|
||||
modelPart.addRelationship(imagePartName, TargetMode.INTERNAL, XSSFWorkbook.IMAGES.getRelation(), getOriginalId());
|
||||
PackagePart imagePart = modelPart.getPackage().createPart(imagePartName, XSSFWorkbook.IMAGES.getContentType());
|
||||
out = imagePart.getOutputStream();
|
||||
picture.writeTo(out);
|
||||
out.close();
|
||||
pictureIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<XSSFPictureData> getPictures()
|
||||
{
|
||||
return this.pictures;
|
||||
}
|
||||
|
||||
public void addPictures(XSSFPictureData picture)
|
||||
{
|
||||
this.pictures.add(picture);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
package org.apache.poi.xssf.model;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
|
||||
/**
|
||||
* Common interface for XSSF models, which have (typically
|
||||
* binary) children to them.
|
||||
* One example is a VmlDrawing (Drawing), which can have
|
||||
* raw images associated with it.
|
||||
*/
|
||||
public interface XSSFChildContainingModel extends XSSFModel {
|
||||
/**
|
||||
* Find any children associated with the {@link XSSFModel}.
|
||||
* @param modelPart The PackagePart of this model
|
||||
*/
|
||||
public void findChildren(PackagePart modelPart) throws IOException, InvalidFormatException;
|
||||
/**
|
||||
* Writes out any children associated with the {@link XSSFModel},
|
||||
* along with the required relationship stuff.
|
||||
* @param modelPart The new PackagePart of this model
|
||||
*/
|
||||
public void writeChildren(PackagePart modelPart) throws IOException, InvalidFormatException;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package org.apache.poi.xssf.usermodel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.poi.ss.usermodel.PictureData;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
|
||||
public class XSSFActiveXData implements PictureData {
|
||||
|
||||
private PackagePart packagePart;
|
||||
private String originalId;
|
||||
|
||||
public XSSFActiveXData(PackagePart packagePart, String originalId) {
|
||||
this(packagePart);
|
||||
this.originalId = originalId;
|
||||
}
|
||||
|
||||
public XSSFActiveXData(PackagePart packagePart) {
|
||||
this.packagePart = packagePart;
|
||||
}
|
||||
|
||||
public String getOriginalId() {
|
||||
return originalId;
|
||||
}
|
||||
|
||||
public PackagePart getPart() {
|
||||
return packagePart;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
IOUtils.copy(packagePart.getInputStream(), out);
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
// TODO - is this right?
|
||||
// Are there headers etc?
|
||||
try {
|
||||
return IOUtils.toByteArray(packagePart.getInputStream());
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String suggestFileExtension() {
|
||||
return packagePart.getPartName().getExtension();
|
||||
}
|
||||
}
|
|
@ -17,26 +17,51 @@
|
|||
|
||||
package org.apache.poi.xssf.usermodel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.poi.ss.usermodel.PictureData;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
|
||||
|
||||
/**
|
||||
* Raw picture data, normally attached to a
|
||||
* vmlDrawing
|
||||
*/
|
||||
public class XSSFPictureData implements PictureData {
|
||||
|
||||
private PackagePart packagePart;
|
||||
private String originalId;
|
||||
|
||||
public XSSFPictureData(PackagePart packagePart, String originalId) {
|
||||
this(packagePart);
|
||||
this.originalId = originalId;
|
||||
}
|
||||
|
||||
public XSSFPictureData(PackagePart packagePart) {
|
||||
this.packagePart = packagePart;
|
||||
}
|
||||
|
||||
public String getOriginalId() {
|
||||
return originalId;
|
||||
}
|
||||
|
||||
protected PackagePart getPart() {
|
||||
return packagePart;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
IOUtils.copy(packagePart.getInputStream(), out);
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
try {
|
||||
return IOUtils.toByteArray(packagePart.getInputStream());
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String suggestFileExtension() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return packagePart.getPartName().getExtension();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ import org.apache.poi.ss.usermodel.Sheet;
|
|||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.ss.util.Region;
|
||||
import org.apache.poi.xssf.model.CommentsTable;
|
||||
import org.apache.poi.xssf.model.Control;
|
||||
import org.apache.poi.xssf.model.Drawing;
|
||||
import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
|
@ -77,6 +79,8 @@ public class XSSFSheet implements Sheet {
|
|||
protected XSSFWorkbook workbook;
|
||||
protected CommentsSource sheetComments;
|
||||
protected CTMergeCells ctMergeCells;
|
||||
protected ArrayList<Drawing> drawings;
|
||||
protected ArrayList<Control> controls;
|
||||
|
||||
public static final short LeftMargin = 0;
|
||||
public static final short RightMargin = 1;
|
||||
|
@ -85,6 +89,22 @@ public class XSSFSheet implements Sheet {
|
|||
public static final short HeaderMargin = 4;
|
||||
public static final short FooterMargin = 5;
|
||||
|
||||
public XSSFSheet(CTSheet sheet, CTWorksheet worksheet, XSSFWorkbook workbook, CommentsSource sheetComments, ArrayList<Drawing> drawings, ArrayList<Control> controls) {
|
||||
this(sheet, worksheet, workbook, sheetComments);
|
||||
this.drawings = drawings;
|
||||
this.controls = controls;
|
||||
}
|
||||
|
||||
public ArrayList<Drawing> getDrawings()
|
||||
{
|
||||
return drawings;
|
||||
}
|
||||
|
||||
public ArrayList<Control> getControls()
|
||||
{
|
||||
return controls;
|
||||
}
|
||||
|
||||
public XSSFSheet(CTSheet sheet, CTWorksheet worksheet, XSSFWorkbook workbook, CommentsSource sheetComments) {
|
||||
this(sheet, worksheet, workbook);
|
||||
this.sheetComments = sheetComments;
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -46,6 +47,8 @@ import org.apache.poi.util.POILogFactory;
|
|||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.xssf.model.BinaryPart;
|
||||
import org.apache.poi.xssf.model.CommentsTable;
|
||||
import org.apache.poi.xssf.model.Control;
|
||||
import org.apache.poi.xssf.model.Drawing;
|
||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.apache.poi.xssf.model.StylesTable;
|
||||
import org.apache.poi.xssf.model.XSSFModel;
|
||||
|
@ -110,10 +113,16 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
|
|||
"/xl/drawings/drawing#.xml",
|
||||
null
|
||||
);
|
||||
public static final XSSFRelation VML_DRAWINGS = new XSSFRelation(
|
||||
"application/vnd.openxmlformats-officedocument.vmlDrawing",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
|
||||
"/xl/drawings/vmlDrawing#.vml",
|
||||
null
|
||||
);
|
||||
public static final XSSFRelation IMAGES = new XSSFRelation(
|
||||
null, // TODO
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
||||
"/xl/image#.xml",
|
||||
"image/x-emf", // TODO
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
||||
"/xl/media/image#.emf",
|
||||
null
|
||||
);
|
||||
public static final XSSFRelation SHEET_COMMENTS = new XSSFRelation(
|
||||
|
@ -140,12 +149,25 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
|
|||
null,
|
||||
BinaryPart.class
|
||||
);
|
||||
|
||||
public static final XSSFRelation VBA_MACROS = new XSSFRelation(
|
||||
"application/vnd.ms-office.vbaProject",
|
||||
"http://schemas.microsoft.com/office/2006/relationships/vbaProject",
|
||||
"/xl/vbaProject.bin",
|
||||
BinaryPart.class
|
||||
);
|
||||
public static final XSSFRelation ACTIVEX_CONTROLS = new XSSFRelation(
|
||||
"application/vnd.ms-office.activeX+xml",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/control",
|
||||
"/xl/activeX/activeX#.xml",
|
||||
null
|
||||
);
|
||||
public static final XSSFRelation ACTIVEX_BINS = new XSSFRelation(
|
||||
"application/vnd.ms-office.activeX",
|
||||
"http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary",
|
||||
"/xl/activeX/activeX#.bin",
|
||||
BinaryPart.class
|
||||
);
|
||||
|
||||
|
||||
public static class XSSFRelation {
|
||||
|
@ -335,9 +357,27 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
|
|||
comments = new CommentsTable(commentsPart.getInputStream());
|
||||
}
|
||||
|
||||
// Get the drawings for the sheet, if there are any
|
||||
ArrayList<Drawing> drawings = new ArrayList<Drawing>();
|
||||
for(PackageRelationship rel : part.getRelationshipsByType(VML_DRAWINGS.REL)) {
|
||||
PackagePart drawingPart = getTargetPart(rel);
|
||||
Drawing drawing = new Drawing(drawingPart.getInputStream(), rel.getId());
|
||||
drawing.findChildren(drawingPart);
|
||||
drawings.add(drawing);
|
||||
}
|
||||
|
||||
// Get the activeX controls for the sheet, if there are any
|
||||
ArrayList<Control> controls = new ArrayList<Control>();
|
||||
for(PackageRelationship rel : part.getRelationshipsByType(ACTIVEX_CONTROLS.REL)) {
|
||||
PackagePart controlPart = getTargetPart(rel);
|
||||
Control control = new Control(controlPart.getInputStream(), rel.getId());
|
||||
control.findChildren(controlPart);
|
||||
controls.add(control);
|
||||
}
|
||||
|
||||
// Now create the sheet
|
||||
WorksheetDocument worksheetDoc = WorksheetDocument.Factory.parse(part.getInputStream());
|
||||
XSSFSheet sheet = new XSSFSheet(ctSheet, worksheetDoc.getWorksheet(), this, comments);
|
||||
XSSFSheet sheet = new XSSFSheet(ctSheet, worksheetDoc.getWorksheet(), this, comments, drawings, controls);
|
||||
this.sheets.add(sheet);
|
||||
|
||||
// Process external hyperlinks for the sheet,
|
||||
|
@ -839,6 +879,40 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
|
|||
ct.writeTo(out);
|
||||
out.close();
|
||||
}
|
||||
|
||||
// If our sheet has drawings, then write out those
|
||||
if(sheet.getDrawings() != null) {
|
||||
int drawingIndex = 1;
|
||||
for(Drawing drawing : sheet.getDrawings()) {
|
||||
PackagePartName drName = PackagingURIHelper.createPartName(
|
||||
VML_DRAWINGS.getFileName(drawingIndex));
|
||||
part.addRelationship(drName, TargetMode.INTERNAL, VML_DRAWINGS.getRelation(), drawing.getOriginalId());
|
||||
PackagePart drPart = pkg.createPart(drName, VML_DRAWINGS.getContentType());
|
||||
|
||||
drawing.writeChildren(drPart);
|
||||
out = drPart.getOutputStream();
|
||||
drawing.writeTo(out);
|
||||
out.close();
|
||||
drawingIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// If our sheet has controls, then write out those
|
||||
if(sheet.getControls() != null) {
|
||||
int controlIndex = 1;
|
||||
for(Control control : sheet.getControls()) {
|
||||
PackagePartName crName = PackagingURIHelper.createPartName(
|
||||
ACTIVEX_CONTROLS.getFileName(controlIndex));
|
||||
part.addRelationship(crName, TargetMode.INTERNAL, ACTIVEX_CONTROLS.getRelation(), control.getOriginalId());
|
||||
PackagePart crPart = pkg.createPart(crName, ACTIVEX_CONTROLS.getContentType());
|
||||
|
||||
control.writeChildren(crPart);
|
||||
out = crPart.getOutputStream();
|
||||
control.writeTo(out);
|
||||
out.close();
|
||||
controlIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write shared strings and styles
|
||||
|
|
|
@ -55,6 +55,7 @@ public class TestXSSFBugs extends TestCase {
|
|||
*/
|
||||
public void test45430() throws Exception {
|
||||
XSSFWorkbook wb = new XSSFWorkbook(getFilePath("45430.xlsx"));
|
||||
assertFalse(wb.isMacroEnabled());
|
||||
assertEquals(3, wb.getNumberOfNames());
|
||||
|
||||
assertEquals(0, wb.getNameAt(0).getCTName().getLocalSheetId());
|
||||
|
@ -85,6 +86,7 @@ public class TestXSSFBugs extends TestCase {
|
|||
public void test45431() throws Exception {
|
||||
Package pkg = Package.open(getFilePath("45431.xlsm"));
|
||||
XSSFWorkbook wb = new XSSFWorkbook(pkg);
|
||||
assertTrue(wb.isMacroEnabled());
|
||||
|
||||
// Check the various macro related bits can be found
|
||||
PackagePart vba = pkg.getPart(
|
||||
|
@ -95,6 +97,7 @@ public class TestXSSFBugs extends TestCase {
|
|||
// Save and re-open, is still there
|
||||
Package nPkg = saveAndOpen(wb);
|
||||
XSSFWorkbook nwb = new XSSFWorkbook(nPkg);
|
||||
assertTrue(nwb.isMacroEnabled());
|
||||
vba = nPkg.getPart(
|
||||
PackagingURIHelper.createPartName("/xl/vbaProject.bin")
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue