From a8fd70ec7fba1b66474f1fdde159b4764ad83c41 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Fri, 26 Oct 2018 09:32:57 +0000 Subject: [PATCH] Adjust sample for creating comments to also create a .xlsx file Enhance workbook factory to allow to create new empty workbooks as well git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1844881 13f79535-47bb-0310-9956-ffa450edef68 --- .../hssf/usermodel/examples/CellComments.java | 74 ++++++++++++------- .../hssf/usermodel/HSSFWorkbookFactory.java | 9 +++ .../poi/ss/usermodel/WorkbookFactory.java | 18 +++++ .../exceptions/InvalidFormatException.java | 2 +- .../apache/poi/openxml4j/opc/OPCPackage.java | 2 + .../xssf/usermodel/XSSFWorkbookFactory.java | 15 ++-- .../apache/poi/ss/TestWorkbookFactory.java | 71 ++++++++++-------- 7 files changed, 129 insertions(+), 62 deletions(-) diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/CellComments.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/CellComments.java index b14cc53abe..877708bde8 100644 --- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/CellComments.java +++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/CellComments.java @@ -17,19 +17,23 @@ package org.apache.poi.hssf.usermodel.examples; +import org.apache.poi.hssf.usermodel.HSSFComment; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.Comment; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.Drawing; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.RichTextString; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; + import java.io.FileOutputStream; import java.io.IOException; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFClientAnchor; -import org.apache.poi.hssf.usermodel.HSSFComment; -import org.apache.poi.hssf.usermodel.HSSFFont; -import org.apache.poi.hssf.usermodel.HSSFPatriarch; -import org.apache.poi.hssf.usermodel.HSSFRichTextString; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.util.HSSFColor.HSSFColorPredefined; - /** * Demonstrates how to work with excel cell comments.

* @@ -39,46 +43,64 @@ import org.apache.poi.hssf.util.HSSFColor.HSSFColorPredefined; public class CellComments { public static void main(String[] args) throws IOException { - try (HSSFWorkbook wb = new HSSFWorkbook()) { - HSSFSheet sheet = wb.createSheet("Cell comments in POI HSSF"); + createWorkbook(false, ".xls"); + createWorkbook(true, ".xlsx"); + } + + private static void createWorkbook(boolean xssf, String extension) throws IOException { + try (Workbook wb = WorkbookFactory.create(xssf)) { + Sheet sheet = wb.createSheet("Cell comments in POI " + extension); + CreationHelper creationHelper = wb.getCreationHelper(); // Create the drawing patriarch. This is the top level container for all shapes including cell comments. - HSSFPatriarch patr = sheet.createDrawingPatriarch(); + Drawing patr = sheet.createDrawingPatriarch(); //create a cell in row 3 - HSSFCell cell1 = sheet.createRow(3).createCell(1); - cell1.setCellValue(new HSSFRichTextString("Hello, World")); + Cell cell1 = sheet.createRow(3).createCell(1); + cell1.setCellValue(creationHelper.createRichTextString("Hello, World")); //anchor defines size and position of the comment in worksheet - HSSFComment comment1 = patr.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5)); + ClientAnchor clientAnchor = creationHelper.createClientAnchor(); + clientAnchor.setCol1(4); + clientAnchor.setRow1(2); + clientAnchor.setCol2(6); + clientAnchor.setRow2(5); + Comment comment1 = patr.createCellComment(clientAnchor); // set text in the comment - comment1.setString(new HSSFRichTextString("We can set comments in POI")); + comment1.setString(creationHelper.createRichTextString("We can set comments in POI")); //set comment author. //you can see it in the status bar when moving mouse over the commented cell comment1.setAuthor("Apache Software Foundation"); - // The first way to assign comment to a cell is via HSSFCell.setCellComment method + // The first way to assign comment to a cell is via Cell.setCellComment method cell1.setCellComment(comment1); //create another cell in row 6 - HSSFCell cell2 = sheet.createRow(6).createCell(1); + Cell cell2 = sheet.createRow(6).createCell(1); cell2.setCellValue(36.6); - HSSFComment comment2 = patr.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 8, (short) 6, 11)); - //modify background color of the comment - comment2.setFillColor(204, 236, 255); + clientAnchor = creationHelper.createClientAnchor(); + clientAnchor.setCol1(4); + clientAnchor.setRow1(8); + clientAnchor.setCol2(6); + clientAnchor.setRow2(11); + Comment comment2 = patr.createCellComment(clientAnchor); + //modify background color of the comment, only available in HSSF currently + if (wb instanceof HSSFWorkbook) { + ((HSSFComment) comment2).setFillColor(204, 236, 255); + } - HSSFRichTextString string = new HSSFRichTextString("Normal body temperature"); + RichTextString string = creationHelper.createRichTextString("Normal body temperature"); //apply custom font to the text in the comment - HSSFFont font = wb.createFont(); + Font font = wb.createFont(); font.setFontName("Arial"); font.setFontHeightInPoints((short) 10); font.setBold(true); - font.setColor(HSSFColorPredefined.RED.getIndex()); + font.setColor(IndexedColors.RED.getIndex()); string.applyFont(font); comment2.setString(string); @@ -94,7 +116,7 @@ public class CellComments { comment2.setRow(6); comment2.setColumn(1); - try (FileOutputStream out = new FileOutputStream("poi_comment.xls")) { + try (FileOutputStream out = new FileOutputStream("poi_comment" + extension)) { wb.write(out); } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbookFactory.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbookFactory.java index e1413aad3b..96196707f6 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbookFactory.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbookFactory.java @@ -31,6 +31,15 @@ import org.apache.poi.util.Internal; @SuppressWarnings("unused") @Internal public class HSSFWorkbookFactory extends WorkbookFactory { + /** + * Create a new empty Workbook + * + * @return The created workbook + */ + public static HSSFWorkbook createWorkbook() { + return new HSSFWorkbook(); + } + /** * Creates a HSSFWorkbook from the given NPOIFSFileSystem

* Note that in order to properly release resources the diff --git a/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java b/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java index aae8c043ce..832795a07f 100644 --- a/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java +++ b/src/java/org/apache/poi/ss/usermodel/WorkbookFactory.java @@ -43,6 +43,24 @@ import org.apache.poi.util.Removal; * by auto-detecting from the supplied input. */ public class WorkbookFactory { + /** + * Create a new empty Workbook, either XSSF or HSSF depending + * on the parameter + * + * @param xssf If an XSSFWorkbook or a HSSFWorkbook should be created + * + * @return The created workbook + * + * @throws IOException if an error occurs while reading the data + */ + public static Workbook create(boolean xssf) throws IOException { + if(xssf) { + return createXSSFWorkbook(); + } else { + return createHSSFWorkbook(); + } + } + /** * Creates a HSSFWorkbook from the given NPOIFSFileSystem

* diff --git a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java index 832d47623b..0cf0cfbc19 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/exceptions/InvalidFormatException.java @@ -18,7 +18,7 @@ package org.apache.poi.openxml4j.exceptions; @SuppressWarnings("serial") -public final class InvalidFormatException extends OpenXML4JException{ +public final class InvalidFormatException extends OpenXML4JException { public InvalidFormatException(String message){ super(message); diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java index 9625a86ff9..767abc239d 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java @@ -291,6 +291,8 @@ public abstract class OPCPackage implements RelationshipSource, Closeable { * @param in * The InputStream to read the package from * @return A PackageBase object + * + * @throws InvalidFormatException */ public static OPCPackage open(InputStream in) throws InvalidFormatException, IOException { diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbookFactory.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbookFactory.java index 482654e8f9..7f72c163eb 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbookFactory.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbookFactory.java @@ -29,6 +29,14 @@ import org.apache.poi.openxml4j.opc.ZipPackage; import org.apache.poi.ss.usermodel.WorkbookFactory; public class XSSFWorkbookFactory extends WorkbookFactory { + /** + * Create a new empty Workbook + * + * @return The created workbook + */ + public static XSSFWorkbook createWorkbook() { + return new XSSFWorkbook(); + } /** * Creates a XSSFWorkbook from the given OOXML Package. @@ -42,7 +50,6 @@ public class XSSFWorkbookFactory extends WorkbookFactory { * @return The created Workbook * * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException */ public static XSSFWorkbook create(OPCPackage pkg) throws IOException { return createWorkbook(pkg); @@ -59,7 +66,6 @@ public class XSSFWorkbookFactory extends WorkbookFactory { * @return The created Workbook * * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException */ public static XSSFWorkbook createWorkbook(ZipPackage pkg) throws IOException { return createWorkbook((OPCPackage)pkg); @@ -76,7 +82,6 @@ public class XSSFWorkbookFactory extends WorkbookFactory { * @return The created Workbook * * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException */ public static XSSFWorkbook createWorkbook(OPCPackage pkg) throws IOException { try { @@ -122,13 +127,11 @@ public class XSSFWorkbookFactory extends WorkbookFactory { * @return The created Workbook * * @throws IOException if an error occurs while reading the data - * @throws InvalidFormatException + * @throws InvalidFormatException if the package is not valid. */ @SuppressWarnings("resource") public static XSSFWorkbook createWorkbook(InputStream stream) throws IOException, InvalidFormatException { OPCPackage pkg = OPCPackage.open(stream); return createWorkbook(pkg); } - - } diff --git a/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java b/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java index 32978df88c..878b536ec2 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java +++ b/src/ooxml/testcases/org/apache/poi/ss/TestWorkbookFactory.java @@ -48,8 +48,8 @@ import org.junit.Test; public final class TestWorkbookFactory { private static final String xls = "SampleSS.xls"; private static final String xlsx = "SampleSS.xlsx"; - private static final String[] xls_prot = new String[] {"password.xls", "password"}; - private static final String[] xlsx_prot = new String[]{"protected_passtika.xlsx", "tika"}; + private static final String[] xls_protected = new String[] {"password.xls", "password"}; + private static final String[] xlsx_protected = new String[]{"protected_passtika.xlsx", "tika"}; private static final String txt = "SampleSS.txt"; private static final POILogger LOGGER = POILogFactory.getLogger(TestWorkbookFactory.class); @@ -199,7 +199,6 @@ public final class TestWorkbookFactory { public void testCreateWithPasswordFromStream() throws Exception { Workbook wb; - // Unprotected, no password given, opens normally wb = WorkbookFactory.create( HSSFTestDataSamples.openSampleFileStream(xls), null @@ -234,26 +233,26 @@ public final class TestWorkbookFactory { // Protected, correct password, opens fine wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), xls_prot[1] + HSSFTestDataSamples.openSampleFileStream(xls_protected[0]), xls_protected[1] ); assertNotNull(wb); assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls_prot[0], wb); + assertCloseDoesNotModifyFile(xls_protected[0], wb); wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), xlsx_prot[1] + HSSFTestDataSamples.openSampleFileStream(xlsx_protected[0]), xlsx_protected[1] ); assertNotNull(wb); assertTrue(wb instanceof XSSFWorkbook); - assertCloseDoesNotModifyFile(xlsx_prot[0], wb); + assertCloseDoesNotModifyFile(xlsx_protected[0], wb); // Protected, wrong password, throws Exception try { wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), "wrong" + HSSFTestDataSamples.openSampleFileStream(xls_protected[0]), "wrong" ); - assertCloseDoesNotModifyFile(xls_prot[0], wb); + assertCloseDoesNotModifyFile(xls_protected[0], wb); fail("Shouldn't be able to open with the wrong password"); } catch (EncryptedDocumentException e) { // expected here @@ -261,9 +260,9 @@ public final class TestWorkbookFactory { try { wb = WorkbookFactory.create( - HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), "wrong" + HSSFTestDataSamples.openSampleFileStream(xlsx_protected[0]), "wrong" ); - assertCloseDoesNotModifyFile(xlsx_prot[0], wb); + assertCloseDoesNotModifyFile(xlsx_protected[0], wb); fail("Shouldn't be able to open with the wrong password"); } catch (EncryptedDocumentException e) { // expected here @@ -309,28 +308,28 @@ public final class TestWorkbookFactory { // Protected, correct password, opens fine wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xls_prot[0]), xls_prot[1] + HSSFTestDataSamples.getSampleFile(xls_protected[0]), xls_protected[1] ); assertNotNull(wb); assertTrue(wb instanceof HSSFWorkbook); - assertCloseDoesNotModifyFile(xls_prot[0], wb); + assertCloseDoesNotModifyFile(xls_protected[0], wb); wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), xlsx_prot[1] + HSSFTestDataSamples.getSampleFile(xlsx_protected[0]), xlsx_protected[1] ); assertNotNull(wb); assertTrue(wb instanceof XSSFWorkbook); assertTrue(wb.getNumberOfSheets() > 0); assertNotNull(wb.getSheetAt(0)); assertNotNull(wb.getSheetAt(0).getRow(0)); - assertCloseDoesNotModifyFile(xlsx_prot[0], wb); + assertCloseDoesNotModifyFile(xlsx_protected[0], wb); // Protected, wrong password, throws Exception try { wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xls_prot[0]), "wrong" + HSSFTestDataSamples.getSampleFile(xls_protected[0]), "wrong" ); - assertCloseDoesNotModifyFile(xls_prot[0], wb); + assertCloseDoesNotModifyFile(xls_protected[0], wb); fail("Shouldn't be able to open with the wrong password"); } catch (EncryptedDocumentException e) { // expected here @@ -338,9 +337,9 @@ public final class TestWorkbookFactory { try { wb = WorkbookFactory.create( - HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), "wrong" + HSSFTestDataSamples.getSampleFile(xlsx_protected[0]), "wrong" ); - assertCloseDoesNotModifyFile(xlsx_prot[0], wb); + assertCloseDoesNotModifyFile(xlsx_protected[0], wb); fail("Shouldn't be able to open with the wrong password"); } catch (EncryptedDocumentException e) { // expected here @@ -397,22 +396,22 @@ public final class TestWorkbookFactory { */ @Test public void testFileSubclass() throws Exception { - Workbook wb; - File normalXLS = HSSFTestDataSamples.getSampleFile(xls); File normalXLSX = HSSFTestDataSamples.getSampleFile(xlsx); File altXLS = new TestFile(normalXLS.getAbsolutePath()); File altXLSX = new TestFile(normalXLSX.getAbsolutePath()); assertTrue(altXLS.exists()); assertTrue(altXLSX.exists()); - - wb = WorkbookFactory.create(altXLS); - assertNotNull(wb); - assertTrue(wb instanceof HSSFWorkbook); - - wb = WorkbookFactory.create(altXLSX); - assertNotNull(wb); - assertTrue(wb instanceof XSSFWorkbook); + + try (Workbook wb = WorkbookFactory.create(altXLS)) { + assertNotNull(wb); + assertTrue(wb instanceof HSSFWorkbook); + } + + try (Workbook wb = WorkbookFactory.create(altXLSX)) { + assertNotNull(wb); + assertTrue(wb instanceof XSSFWorkbook); + } } private static class TestFile extends File { @@ -420,4 +419,18 @@ public final class TestWorkbookFactory { super(file); } } + + /** + * Check that the overloaded file methods which take passwords work properly + */ + @Test + public void testCreateEmpty() throws Exception { + try (Workbook wb = WorkbookFactory.create(false)) { + assertTrue(wb instanceof HSSFWorkbook); + } + + try (Workbook wb = WorkbookFactory.create(true)) { + assertTrue(wb instanceof XSSFWorkbook); + } + } }