From c090d999071f72f65cc005bdb920d664c41fa86c Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Tue, 29 Jul 2008 22:02:09 +0000 Subject: [PATCH] Improved .xlsm support - still not quite there though git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@680857 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xssf/usermodel/XSSFWorkbook.java | 50 +++++++++++++++---- .../poi/xssf/usermodel/TestXSSFBugs.java | 6 +++ 2 files changed, 45 insertions(+), 11 deletions(-) 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 c98135d58..3c395264e 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -80,6 +80,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { "/xl/workbook.xml", null ); + public static final XSSFRelation MACROS_WORKBOOK = new XSSFRelation( + "application/vnd.ms-excel.sheet.macroEnabled.main+xml", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", + "/xl/workbook.xml", + null + ); public static final XSSFRelation WORKSHEET = new XSSFRelation( "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", @@ -254,6 +260,9 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { return rel.getId(); } } + + /** Are we a normal workbook, or a macro enabled one? */ + private boolean isMacroEnabled = false; private CTWorkbook workbook; @@ -288,6 +297,10 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { WorkbookDocument doc = WorkbookDocument.Factory.parse(getCorePart().getInputStream()); this.workbook = doc.getWorkbook(); + // Are we macro enabled, or just normal? + isMacroEnabled = + getCorePart().getContentType().equals(MACROS_WORKBOOK.getContentType()); + try { // Load shared strings this.sharedStringSource = (SharedStringSource) @@ -659,6 +672,14 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { } return sr; } + + /** + * Are we a normal workbook (.xlsx), or a + * macro enabled workbook (.xlsm)? + */ + public boolean isMacroEnabled() { + return isMacroEnabled; + } public void insertChartRecord() { // TODO Auto-generated method stub @@ -764,16 +785,21 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { } public void write(OutputStream stream) throws IOException { + // What kind of workbook are we? + XSSFRelation workbookRelation = WORKBOOK; + if(isMacroEnabled) { + workbookRelation = MACROS_WORKBOOK; + } try { // Create a package referring the temp file. Package pkg = Package.create(stream); // Main part - PackagePartName corePartName = PackagingURIHelper.createPartName("/xl/workbook.xml"); + PackagePartName corePartName = PackagingURIHelper.createPartName(workbookRelation.getDefaultFileName()); // Create main part relationship pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT, "rId1"); // Create main document part - PackagePart corePart = pkg.createPart(corePartName, WORKBOOK.getContentType()); + PackagePart corePart = pkg.createPart(corePartName, workbookRelation.getContentType()); OutputStream out; XmlOptions xmlOptions = new XmlOptions(); @@ -840,15 +866,17 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { } } - // VBA Macros - if(VBA_MACROS.exists( getCorePart() )) { - // Copy over - try { - XSSFModel vba = VBA_MACROS.load(getCorePart()); - VBA_MACROS.save(vba, corePart); - } catch(Exception e) { - throw new RuntimeException("Unable to copy vba macros over", e); - } + // Macro related bits + if(isMacroEnabled) { + // Copy VBA Macros if present + if(VBA_MACROS.exists( getCorePart() )) { + try { + XSSFModel vba = VBA_MACROS.load(getCorePart()); + VBA_MACROS.save(vba, corePart); + } catch(Exception e) { + throw new RuntimeException("Unable to copy vba macros over", e); + } + } } // Now we can write out the main Workbook, with diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index 045f42cb0..518a15f56 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -20,6 +20,7 @@ package org.apache.poi.xssf.usermodel; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileOutputStream; import junit.framework.TestCase; @@ -85,6 +86,7 @@ public class TestXSSFBugs extends TestCase { Package pkg = Package.open(getFilePath("45431.xlsm")); XSSFWorkbook wb = new XSSFWorkbook(pkg); + // Check the various macro related bits can be found PackagePart vba = pkg.getPart( PackagingURIHelper.createPartName("/xl/vbaProject.bin") ); @@ -106,6 +108,10 @@ public class TestXSSFBugs extends TestCase { ); assertNotNull(vba); + FileOutputStream fout = new FileOutputStream("/tmp/foo.xlsm"); + nwb.write(fout); + fout.close(); + // For testing with excel // FileOutputStream fout = new FileOutputStream("/tmp/foo.xlsm"); // nwb.write(fout);