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
This commit is contained in:
Dominik Stadler 2018-10-26 09:32:57 +00:00
parent 1d464ed131
commit a8fd70ec7f
7 changed files with 129 additions and 62 deletions

View File

@ -17,19 +17,23 @@
package org.apache.poi.hssf.usermodel.examples; 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.FileOutputStream;
import java.io.IOException; 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.<p> * Demonstrates how to work with excel cell comments.<p>
* *
@ -39,46 +43,64 @@ import org.apache.poi.hssf.util.HSSFColor.HSSFColorPredefined;
public class CellComments { public class CellComments {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
try (HSSFWorkbook wb = new HSSFWorkbook()) { createWorkbook(false, ".xls");
HSSFSheet sheet = wb.createSheet("Cell comments in POI HSSF"); 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. // 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 //create a cell in row 3
HSSFCell cell1 = sheet.createRow(3).createCell(1); Cell cell1 = sheet.createRow(3).createCell(1);
cell1.setCellValue(new HSSFRichTextString("Hello, World")); cell1.setCellValue(creationHelper.createRichTextString("Hello, World"));
//anchor defines size and position of the comment in worksheet //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 // 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. //set comment author.
//you can see it in the status bar when moving mouse over the commented cell //you can see it in the status bar when moving mouse over the commented cell
comment1.setAuthor("Apache Software Foundation"); 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); cell1.setCellComment(comment1);
//create another cell in row 6 //create another cell in row 6
HSSFCell cell2 = sheet.createRow(6).createCell(1); Cell cell2 = sheet.createRow(6).createCell(1);
cell2.setCellValue(36.6); cell2.setCellValue(36.6);
HSSFComment comment2 = patr.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 8, (short) 6, 11)); clientAnchor = creationHelper.createClientAnchor();
//modify background color of the comment clientAnchor.setCol1(4);
comment2.setFillColor(204, 236, 255); 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 //apply custom font to the text in the comment
HSSFFont font = wb.createFont(); Font font = wb.createFont();
font.setFontName("Arial"); font.setFontName("Arial");
font.setFontHeightInPoints((short) 10); font.setFontHeightInPoints((short) 10);
font.setBold(true); font.setBold(true);
font.setColor(HSSFColorPredefined.RED.getIndex()); font.setColor(IndexedColors.RED.getIndex());
string.applyFont(font); string.applyFont(font);
comment2.setString(string); comment2.setString(string);
@ -94,7 +116,7 @@ public class CellComments {
comment2.setRow(6); comment2.setRow(6);
comment2.setColumn(1); comment2.setColumn(1);
try (FileOutputStream out = new FileOutputStream("poi_comment.xls")) { try (FileOutputStream out = new FileOutputStream("poi_comment" + extension)) {
wb.write(out); wb.write(out);
} }
} }

View File

@ -31,6 +31,15 @@ import org.apache.poi.util.Internal;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Internal @Internal
public class HSSFWorkbookFactory extends WorkbookFactory { 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<p> * Creates a HSSFWorkbook from the given NPOIFSFileSystem<p>
* Note that in order to properly release resources the * Note that in order to properly release resources the

View File

@ -43,6 +43,24 @@ import org.apache.poi.util.Removal;
* by auto-detecting from the supplied input. * by auto-detecting from the supplied input.
*/ */
public class WorkbookFactory { 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<p> * Creates a HSSFWorkbook from the given NPOIFSFileSystem<p>
* *

View File

@ -18,7 +18,7 @@
package org.apache.poi.openxml4j.exceptions; package org.apache.poi.openxml4j.exceptions;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public final class InvalidFormatException extends OpenXML4JException{ public final class InvalidFormatException extends OpenXML4JException {
public InvalidFormatException(String message){ public InvalidFormatException(String message){
super(message); super(message);

View File

@ -291,6 +291,8 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
* @param in * @param in
* The InputStream to read the package from * The InputStream to read the package from
* @return A PackageBase object * @return A PackageBase object
*
* @throws InvalidFormatException
*/ */
public static OPCPackage open(InputStream in) throws InvalidFormatException, public static OPCPackage open(InputStream in) throws InvalidFormatException,
IOException { IOException {

View File

@ -29,6 +29,14 @@ import org.apache.poi.openxml4j.opc.ZipPackage;
import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.ss.usermodel.WorkbookFactory;
public class XSSFWorkbookFactory extends 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. * Creates a XSSFWorkbook from the given OOXML Package.
@ -42,7 +50,6 @@ public class XSSFWorkbookFactory extends WorkbookFactory {
* @return The created Workbook * @return The created Workbook
* *
* @throws IOException if an error occurs while reading the data * @throws IOException if an error occurs while reading the data
* @throws InvalidFormatException
*/ */
public static XSSFWorkbook create(OPCPackage pkg) throws IOException { public static XSSFWorkbook create(OPCPackage pkg) throws IOException {
return createWorkbook(pkg); return createWorkbook(pkg);
@ -59,7 +66,6 @@ public class XSSFWorkbookFactory extends WorkbookFactory {
* @return The created Workbook * @return The created Workbook
* *
* @throws IOException if an error occurs while reading the data * @throws IOException if an error occurs while reading the data
* @throws InvalidFormatException
*/ */
public static XSSFWorkbook createWorkbook(ZipPackage pkg) throws IOException { public static XSSFWorkbook createWorkbook(ZipPackage pkg) throws IOException {
return createWorkbook((OPCPackage)pkg); return createWorkbook((OPCPackage)pkg);
@ -76,7 +82,6 @@ public class XSSFWorkbookFactory extends WorkbookFactory {
* @return The created Workbook * @return The created Workbook
* *
* @throws IOException if an error occurs while reading the data * @throws IOException if an error occurs while reading the data
* @throws InvalidFormatException
*/ */
public static XSSFWorkbook createWorkbook(OPCPackage pkg) throws IOException { public static XSSFWorkbook createWorkbook(OPCPackage pkg) throws IOException {
try { try {
@ -122,13 +127,11 @@ public class XSSFWorkbookFactory extends WorkbookFactory {
* @return The created Workbook * @return The created Workbook
* *
* @throws IOException if an error occurs while reading the data * @throws IOException if an error occurs while reading the data
* @throws InvalidFormatException * @throws InvalidFormatException if the package is not valid.
*/ */
@SuppressWarnings("resource") @SuppressWarnings("resource")
public static XSSFWorkbook createWorkbook(InputStream stream) throws IOException, InvalidFormatException { public static XSSFWorkbook createWorkbook(InputStream stream) throws IOException, InvalidFormatException {
OPCPackage pkg = OPCPackage.open(stream); OPCPackage pkg = OPCPackage.open(stream);
return createWorkbook(pkg); return createWorkbook(pkg);
} }
} }

View File

@ -48,8 +48,8 @@ import org.junit.Test;
public final class TestWorkbookFactory { public final class TestWorkbookFactory {
private static final String xls = "SampleSS.xls"; private static final String xls = "SampleSS.xls";
private static final String xlsx = "SampleSS.xlsx"; private static final String xlsx = "SampleSS.xlsx";
private static final String[] xls_prot = new String[] {"password.xls", "password"}; private static final String[] xls_protected = new String[] {"password.xls", "password"};
private static final String[] xlsx_prot = new String[]{"protected_passtika.xlsx", "tika"}; private static final String[] xlsx_protected = new String[]{"protected_passtika.xlsx", "tika"};
private static final String txt = "SampleSS.txt"; private static final String txt = "SampleSS.txt";
private static final POILogger LOGGER = POILogFactory.getLogger(TestWorkbookFactory.class); private static final POILogger LOGGER = POILogFactory.getLogger(TestWorkbookFactory.class);
@ -199,7 +199,6 @@ public final class TestWorkbookFactory {
public void testCreateWithPasswordFromStream() throws Exception { public void testCreateWithPasswordFromStream() throws Exception {
Workbook wb; Workbook wb;
// Unprotected, no password given, opens normally // Unprotected, no password given, opens normally
wb = WorkbookFactory.create( wb = WorkbookFactory.create(
HSSFTestDataSamples.openSampleFileStream(xls), null HSSFTestDataSamples.openSampleFileStream(xls), null
@ -234,26 +233,26 @@ public final class TestWorkbookFactory {
// Protected, correct password, opens fine // Protected, correct password, opens fine
wb = WorkbookFactory.create( wb = WorkbookFactory.create(
HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), xls_prot[1] HSSFTestDataSamples.openSampleFileStream(xls_protected[0]), xls_protected[1]
); );
assertNotNull(wb); assertNotNull(wb);
assertTrue(wb instanceof HSSFWorkbook); assertTrue(wb instanceof HSSFWorkbook);
assertCloseDoesNotModifyFile(xls_prot[0], wb); assertCloseDoesNotModifyFile(xls_protected[0], wb);
wb = WorkbookFactory.create( wb = WorkbookFactory.create(
HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), xlsx_prot[1] HSSFTestDataSamples.openSampleFileStream(xlsx_protected[0]), xlsx_protected[1]
); );
assertNotNull(wb); assertNotNull(wb);
assertTrue(wb instanceof XSSFWorkbook); assertTrue(wb instanceof XSSFWorkbook);
assertCloseDoesNotModifyFile(xlsx_prot[0], wb); assertCloseDoesNotModifyFile(xlsx_protected[0], wb);
// Protected, wrong password, throws Exception // Protected, wrong password, throws Exception
try { try {
wb = WorkbookFactory.create( 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"); fail("Shouldn't be able to open with the wrong password");
} catch (EncryptedDocumentException e) { } catch (EncryptedDocumentException e) {
// expected here // expected here
@ -261,9 +260,9 @@ public final class TestWorkbookFactory {
try { try {
wb = WorkbookFactory.create( 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"); fail("Shouldn't be able to open with the wrong password");
} catch (EncryptedDocumentException e) { } catch (EncryptedDocumentException e) {
// expected here // expected here
@ -309,28 +308,28 @@ public final class TestWorkbookFactory {
// Protected, correct password, opens fine // Protected, correct password, opens fine
wb = WorkbookFactory.create( wb = WorkbookFactory.create(
HSSFTestDataSamples.getSampleFile(xls_prot[0]), xls_prot[1] HSSFTestDataSamples.getSampleFile(xls_protected[0]), xls_protected[1]
); );
assertNotNull(wb); assertNotNull(wb);
assertTrue(wb instanceof HSSFWorkbook); assertTrue(wb instanceof HSSFWorkbook);
assertCloseDoesNotModifyFile(xls_prot[0], wb); assertCloseDoesNotModifyFile(xls_protected[0], wb);
wb = WorkbookFactory.create( wb = WorkbookFactory.create(
HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), xlsx_prot[1] HSSFTestDataSamples.getSampleFile(xlsx_protected[0]), xlsx_protected[1]
); );
assertNotNull(wb); assertNotNull(wb);
assertTrue(wb instanceof XSSFWorkbook); assertTrue(wb instanceof XSSFWorkbook);
assertTrue(wb.getNumberOfSheets() > 0); assertTrue(wb.getNumberOfSheets() > 0);
assertNotNull(wb.getSheetAt(0)); assertNotNull(wb.getSheetAt(0));
assertNotNull(wb.getSheetAt(0).getRow(0)); assertNotNull(wb.getSheetAt(0).getRow(0));
assertCloseDoesNotModifyFile(xlsx_prot[0], wb); assertCloseDoesNotModifyFile(xlsx_protected[0], wb);
// Protected, wrong password, throws Exception // Protected, wrong password, throws Exception
try { try {
wb = WorkbookFactory.create( 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"); fail("Shouldn't be able to open with the wrong password");
} catch (EncryptedDocumentException e) { } catch (EncryptedDocumentException e) {
// expected here // expected here
@ -338,9 +337,9 @@ public final class TestWorkbookFactory {
try { try {
wb = WorkbookFactory.create( 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"); fail("Shouldn't be able to open with the wrong password");
} catch (EncryptedDocumentException e) { } catch (EncryptedDocumentException e) {
// expected here // expected here
@ -397,22 +396,22 @@ public final class TestWorkbookFactory {
*/ */
@Test @Test
public void testFileSubclass() throws Exception { public void testFileSubclass() throws Exception {
Workbook wb;
File normalXLS = HSSFTestDataSamples.getSampleFile(xls); File normalXLS = HSSFTestDataSamples.getSampleFile(xls);
File normalXLSX = HSSFTestDataSamples.getSampleFile(xlsx); File normalXLSX = HSSFTestDataSamples.getSampleFile(xlsx);
File altXLS = new TestFile(normalXLS.getAbsolutePath()); File altXLS = new TestFile(normalXLS.getAbsolutePath());
File altXLSX = new TestFile(normalXLSX.getAbsolutePath()); File altXLSX = new TestFile(normalXLSX.getAbsolutePath());
assertTrue(altXLS.exists()); assertTrue(altXLS.exists());
assertTrue(altXLSX.exists()); assertTrue(altXLSX.exists());
wb = WorkbookFactory.create(altXLS); try (Workbook wb = WorkbookFactory.create(altXLS)) {
assertNotNull(wb); assertNotNull(wb);
assertTrue(wb instanceof HSSFWorkbook); assertTrue(wb instanceof HSSFWorkbook);
}
wb = WorkbookFactory.create(altXLSX);
assertNotNull(wb); try (Workbook wb = WorkbookFactory.create(altXLSX)) {
assertTrue(wb instanceof XSSFWorkbook); assertNotNull(wb);
assertTrue(wb instanceof XSSFWorkbook);
}
} }
private static class TestFile extends File { private static class TestFile extends File {
@ -420,4 +419,18 @@ public final class TestWorkbookFactory {
super(file); 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);
}
}
} }