diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2020-04-19 23:37:06 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2020-04-19 23:37:06 +0000 |
commit | 661c0b66bcfbedfa307d547bafb2113c8b9978e6 (patch) | |
tree | aee09bddfdb4f8a729db9f7a8455d85eff137f7b /src/examples | |
parent | c41dee931f95c3d9747c5747316b49504bd15477 (diff) | |
download | poi-661c0b66bcfbedfa307d547bafb2113c8b9978e6.tar.gz poi-661c0b66bcfbedfa307d547bafb2113c8b9978e6.zip |
Sonar fixes
- Math operands should be cast before assignment
- Suppress - Make sure that command line arguments are used safely here
- Suppress - Replace this use of System.out or System.err by a logger.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1876737 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/examples')
16 files changed, 189 insertions, 1184 deletions
diff --git a/src/examples/src/org/apache/poi/crypt/examples/OOXMLPasswordsTry.java b/src/examples/src/org/apache/poi/crypt/examples/OOXMLPasswordsTry.java index 15a91cef16..261020fc79 100644 --- a/src/examples/src/org/apache/poi/crypt/examples/OOXMLPasswordsTry.java +++ b/src/examples/src/org/apache/poi/crypt/examples/OOXMLPasswordsTry.java @@ -25,6 +25,7 @@ import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.util.Optional; import java.util.function.Predicate; +import java.util.stream.Stream; import org.apache.poi.poifs.crypt.Decryptor; import org.apache.poi.poifs.crypt.EncryptionInfo; @@ -50,7 +51,8 @@ public final class OOXMLPasswordsTry { System.err.println(" OOXMLPasswordsTry <file.ooxml> <wordlist>"); System.exit(1); } - String ooxml = args[0], words = args[1]; + String ooxml = args[0]; + String words = args[1]; System.out.println("Trying passwords from " + words + " against " + ooxml); System.out.println(); @@ -61,7 +63,7 @@ public final class OOXMLPasswordsTry { final long start = System.currentTimeMillis(); final int[] count = { 0 }; - Predicate<String> counter = (s) -> { + Predicate<String> counter = s -> { if (++count[0] % 1000 == 0) { int secs = (int) ((System.currentTimeMillis() - start) / 1000); System.out.println("Done " + count[0] + " passwords, " + secs + " seconds, last password " + s); @@ -70,9 +72,10 @@ public final class OOXMLPasswordsTry { }; // Try each password in turn, reporting progress - Optional<String> found = Files.lines(Paths.get(words)).filter(counter).filter(w -> isValid(d, w)).findFirst(); - - System.out.println(found.map(s -> "Password found: " + s).orElse("Error - No password matched")); + try (Stream<String> lines = Files.lines(Paths.get(words))) { + Optional<String> found = lines.filter(counter).filter(w -> isValid(d, w)).findFirst(); + System.out.println(found.map(s -> "Password found: " + s).orElse("Error - No password matched")); + } } } diff --git a/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java b/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java index cf85fe7260..0f47704c97 100644 --- a/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java +++ b/src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java @@ -17,33 +17,27 @@ package org.apache.poi.hpsf.examples; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; -import java.util.HashMap; -import java.util.Map; import org.apache.poi.hpsf.DocumentSummaryInformation; +import org.apache.poi.hpsf.HPSFException; import org.apache.poi.hpsf.HPSFRuntimeException; -import org.apache.poi.hpsf.MarkUnsupportedException; -import org.apache.poi.hpsf.NoPropertySetStreamException; import org.apache.poi.hpsf.PropertySet; import org.apache.poi.hpsf.PropertySetFactory; import org.apache.poi.hpsf.SummaryInformation; -import org.apache.poi.hpsf.UnexpectedPropertySetTypeException; import org.apache.poi.hpsf.WritingNotSupportedException; import org.apache.poi.poifs.eventfilesystem.POIFSReader; import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent; -import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener; import org.apache.poi.poifs.filesystem.DirectoryEntry; import org.apache.poi.poifs.filesystem.DocumentInputStream; import org.apache.poi.poifs.filesystem.EntryUtils; import org.apache.poi.poifs.filesystem.POIFSDocumentPath; import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.util.IOUtils; import org.apache.poi.util.TempFile; /** @@ -89,7 +83,7 @@ public final class CopyCompare { String originalFileName = null; String copyFileName = null; - /* Check the command-line arguments. */ + // Check the command-line arguments. if (args.length == 1) { originalFileName = args[0]; File f = TempFile.createTempFile("CopyOfPOIFileSystem-", ".ole2"); @@ -99,25 +93,26 @@ public final class CopyCompare { originalFileName = args[0]; copyFileName = args[1]; } else { - System.err.println("Usage: " + CopyCompare.class.getName() + - "originPOIFS [copyPOIFS]"); + System.err.println("Usage: CopyCompare originPOIFS [copyPOIFS]"); System.exit(1); } - /* Read the origin POIFS using the eventing API. The real work is done - * in the class CopyFile which is registered here as a POIFSReader. */ + + // Read the origin POIFS using the eventing API. final POIFSReader r = new POIFSReader(); - final CopyFile cf = new CopyFile(copyFileName); - r.registerListener(cf); - r.setNotifyEmptyDirectories(true); + try (final POIFSFileSystem poiFs = new POIFSFileSystem(); + OutputStream fos = new FileOutputStream(copyFileName)) { + r.registerListener(e -> handleEvent(poiFs, e)); + r.setNotifyEmptyDirectories(true); - r.read(new File(originalFileName)); + r.read(new File(originalFileName)); - /* Write the new POIFS to disk. */ - cf.close(); + // Write the new POIFS to disk. + poiFs.writeFilesystem(fos); + } - /* Read all documents from the original POI file system and compare them - * with the equivalent document from the copy. */ + // Read all documents from the original POI file system and compare them with + // the equivalent document from the copy. try (POIFSFileSystem opfs = new POIFSFileSystem(new File(originalFileName)); POIFSFileSystem cpfs = new POIFSFileSystem(new File(copyFileName))) { final DirectoryEntry oRoot = opfs.getRoot(); @@ -126,94 +121,28 @@ public final class CopyCompare { } } + private interface InputStreamSupplier { + InputStream get() throws IOException, WritingNotSupportedException; + } + /** - * <p>This class does all the work. Its method {@link - * #processPOIFSReaderEvent(POIFSReaderEvent)} is called for each file in - * the original POI file system. Except for property set streams it copies - * everything unmodified to the destination POI filesystem. Property set - * streams are copied by creating a new {@link PropertySet} from the - * original property set by using the {@link - * PropertySet#PropertySet(PropertySet)} constructor.</p> + * The method is called by POI's eventing API for each file in the origin POIFS. */ - static class CopyFile implements POIFSReaderListener { - private final String dstName; - private final POIFSFileSystem poiFs; - - - /** - * <p>The constructor of a {@link CopyFile} instance creates the target - * POIFS. It also stores the name of the file the POIFS will be written - * to once it is complete.</p> - * - * @param dstName The name of the disk file the destination POIFS is to - * be written to. - */ - CopyFile(final String dstName) { - this.dstName = dstName; - poiFs = new POIFSFileSystem(); - } - + public static void handleEvent(final POIFSFileSystem poiFs, final POIFSReaderEvent event) { + // The following declarations are shortcuts for accessing the "event" object. + final DocumentInputStream stream = event.getStream(); - /** - * <p>The method is called by POI's eventing API for each file in the - * origin POIFS.</p> - */ - @Override - public void processPOIFSReaderEvent(final POIFSReaderEvent event) { - /* The following declarations are shortcuts for accessing the - * "event" object. */ - final POIFSDocumentPath path = event.getPath(); - final String name = event.getName(); + try { - Throwable t = null; - - try (final DocumentInputStream stream = event.getStream()) { - /* Find out whether the current document is a property set - * stream or not. */ - if (stream != null && PropertySet.isPropertySetStream(stream)) { - /* Yes, the current document is a property set stream. - * Let's create a PropertySet instance from it. */ - PropertySet ps = PropertySetFactory.create(stream); - - /* Copy the property set to the destination POI file - * system. */ - copy(poiFs, path, name, ps); - } else { - /* No, the current document is not a property set stream. We - * copy it unmodified to the destination POIFS. */ - copy(poiFs, path, name, stream); - } - } catch (MarkUnsupportedException | WritingNotSupportedException | IOException | NoPropertySetStreamException ex) { - t = ex; - } - - /* According to the definition of the processPOIFSReaderEvent method - * we cannot pass checked exceptions to the caller. The following - * lines check whether a checked exception occurred and throws an - * unchecked exception. The message of that exception is that of - * the underlying checked exception. */ - if (t != null) { - throw new HPSFRuntimeException("Could not read file \"" + path + "/" + name, t); - } - } + // Find out whether the current document is a property set stream or not. + InputStreamSupplier su; + if (stream != null && PropertySet.isPropertySetStream(stream)) { + // Yes, the current document is a property set stream. Let's create + // a PropertySet instance from it. + PropertySet ps = PropertySetFactory.create(stream); - - /** - * Writes a {@link PropertySet} to a POI filesystem. - * - * @param poiFs The POI filesystem to write to. - * @param path The file's path in the POI filesystem. - * @param name The file's name in the POI filesystem. - * @param ps The property set to write. - */ - public void copy(final POIFSFileSystem poiFs, - final POIFSDocumentPath path, - final String name, - final PropertySet ps) - throws WritingNotSupportedException, IOException { - final DirectoryEntry de = getPath(poiFs, path); - final PropertySet mps; - try { + // Copy the property set to the destination POI file system. + final PropertySet mps; if (ps instanceof DocumentSummaryInformation) { mps = new DocumentSummaryInformation(ps); } else if (ps instanceof SummaryInformation) { @@ -221,112 +150,32 @@ public final class CopyCompare { } else { mps = new PropertySet(ps); } - } catch (UnexpectedPropertySetTypeException e) { - throw new IOException(e); - } - de.createDocument(name, mps.toInputStream()); - } - - - /** - * Copies the bytes from a {@link DocumentInputStream} to a new - * stream in a POI filesystem. - * - * @param poiFs The POI filesystem to write to. - * @param path The source document's path. - * @param name The source document's name. - * @param stream The stream containing the source document. - */ - public void copy(final POIFSFileSystem poiFs, - final POIFSDocumentPath path, - final String name, - final DocumentInputStream stream) - throws IOException { - // create the directories to the document - final DirectoryEntry de = getPath(poiFs, path); - // check the parameters after the directories have been created - if (stream != null && name != null) { - byte[] data = IOUtils.toByteArray(stream); - de.createDocument(name, new ByteArrayInputStream(data)); + su = mps::toInputStream; + } else { + // No, the current document is not a property set stream. + // We copy it unmodified to the destination POIFS. + su = event::getStream; } - } + try (InputStream is = su.get()) { + final POIFSDocumentPath path = event.getPath(); - /** - * Writes the POI file system to a disk file. - */ - public void close() throws IOException { - try (OutputStream fos = new FileOutputStream(dstName)) { - poiFs.writeFilesystem(fos); - } - } + // Ensures that the directory hierarchy for a document in a POI fileystem is in place. + // Get the root directory. It does not have to be created since it always exists in a POIFS. + DirectoryEntry de = poiFs.getRoot(); - - /** - * Contains the directory paths that have already been created in the - * output POI filesystem and maps them to their corresponding - * {@link org.apache.poi.poifs.filesystem.DirectoryNode}s. - */ - private final Map<String, DirectoryEntry> paths = new HashMap<>(); - - - /** - * <p>Ensures that the directory hierarchy for a document in a POI - * fileystem is in place. When a document is to be created somewhere in - * a POI filesystem its directory must be created first. This method - * creates all directories between the POI filesystem root and the - * directory the document should belong to which do not yet exist.</p> - * <p> - * <p>Unfortunately POI does not offer a simple method to interrogate - * the POIFS whether a certain child node (file or directory) exists in - * a directory. However, since we always start with an empty POIFS which - * contains the root directory only and since each directory in the - * POIFS is created by this method we can maintain the POIFS's directory - * hierarchy ourselves: The {@link DirectoryEntry} of each directory - * created is stored in a {@link Map}. The directories' path names map - * to the corresponding {@link DirectoryEntry} instances.</p> - * - * @param poiFs The POI filesystem the directory hierarchy is created - * in, if needed. - * @param path The document's path. This method creates those directory - * components of this hierarchy which do not yet exist. - * @return The directory entry of the document path's parent. The caller - * should use this {@link DirectoryEntry} to create documents in it. - */ - public DirectoryEntry getPath(final POIFSFileSystem poiFs, - final POIFSDocumentPath path) { - try { - /* Check whether this directory has already been created. */ - final String s = path.toString(); - DirectoryEntry de = paths.get(s); - if (de != null) { - /* Yes: return the corresponding DirectoryEntry. */ - return de; + for (int i=0; i<path.length(); i++) { + String subDir = path.getComponent(i); + de = (de.hasEntry(subDir)) ? (DirectoryEntry)de.getEntry(subDir) : de.createDirectory(subDir); } - /* No: We have to create the directory - or return the root's - * DirectoryEntry. */ - int l = path.length(); - if (l == 0) { - /* Get the root directory. It does not have to be created - * since it always exists in a POIFS. */ - de = poiFs.getRoot(); - } else { - /* Create a subordinate directory. The first step is to - * ensure that the parent directory exists: */ - de = getPath(poiFs, path.getParent()); - /* Now create the target directory: */ - de = de.createDirectory(path.getComponent(path.length() - 1)); - } - paths.put(s, de); - return de; - } catch (IOException ex) { - /* This exception will be thrown if the directory already - * exists. However, since we have full control about directory - * creation we can ensure that this will never happen. */ - throw new RuntimeException(ex); + de.createDocument(event.getName(), is); } + + } catch (HPSFException | IOException ex) { + // According to the definition of the processPOIFSReaderEvent method we cannot pass checked + // exceptions to the caller. + throw new HPSFRuntimeException("Could not read file " + event.getPath() + "/" + event.getName(), ex); } } - } diff --git a/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java b/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java index f2b47e6de5..fc8751bda6 100644 --- a/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java +++ b/src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java @@ -21,6 +21,7 @@ import java.io.File; import java.io.IOException; import java.util.List; +import org.apache.poi.hpsf.HPSFRuntimeException; import org.apache.poi.hpsf.NoPropertySetStreamException; import org.apache.poi.hpsf.Property; import org.apache.poi.hpsf.PropertySet; @@ -65,7 +66,7 @@ public final class ReadCustomPropertySets { out("No property set stream: \"" + streamName + "\""); return; } catch (Exception ex) { - throw new RuntimeException("Property set stream \"" + streamName + "\": " + ex); + throw new HPSFRuntimeException("Property set stream \"" + streamName + "\": " + ex); } /* Print the name of the property set stream: */ diff --git a/src/examples/src/org/apache/poi/hpsf/examples/WriteAuthorAndTitle.java b/src/examples/src/org/apache/poi/hpsf/examples/WriteAuthorAndTitle.java index 5a03de0edb..ce51773a25 100644 --- a/src/examples/src/org/apache/poi/hpsf/examples/WriteAuthorAndTitle.java +++ b/src/examples/src/org/apache/poi/hpsf/examples/WriteAuthorAndTitle.java @@ -93,7 +93,8 @@ public final class WriteAuthorAndTitle { } /* Read the names of the origin and destination POI filesystems. */ - final String srcName = args[0], dstName = args[1]; + final String srcName = args[0]; + final String dstName = args[1]; /* Read the origin POIFS using the eventing API. The real work is done * in the class ModifySICopyTheRest which is registered here as a @@ -101,7 +102,7 @@ public final class WriteAuthorAndTitle { try (POIFSFileSystem poifs = new POIFSFileSystem(); OutputStream out = new FileOutputStream(dstName)) { final POIFSReader r = new POIFSReader(); - r.registerListener((e) -> handleEvent(poifs, e)); + r.registerListener(e -> handleEvent(poifs, e)); r.read(new File(srcName)); /* Write the new POIFS to disk. */ diff --git a/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java b/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java index 87877e4ef1..73871cb335 100644 --- a/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java +++ b/src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java @@ -392,7 +392,8 @@ public final class ApacheconEU08 { Graphics2D graphics = new SLGraphics(group); //draw a simple bar graph - int x = bounds.x + 50, y = bounds.y + 50; + int x = bounds.x + 50; + int y = bounds.y + 50; graphics.setFont(new Font("Arial", Font.BOLD, 10)); for (int i = 0, idx = 1; i < def.length; i+=2, idx++) { graphics.setColor(Color.black); diff --git a/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java b/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java index 2c7aac83a2..e73b8971e6 100644 --- a/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java +++ b/src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java @@ -60,42 +60,40 @@ public final class DataExtraction { handleSound(aSound); } - int oleIdx = -1, picIdx = -1; + int oleIdx = -1; + int picIdx = -1; for (HSLFSlide slide : ppt.getSlides()) { //extract embedded OLE documents for (HSLFShape shape : slide.getShapes()) { if (shape instanceof HSLFObjectShape) { - oleIdx++; - HSLFObjectShape ole = (HSLFObjectShape) shape; - HSLFObjectData data = ole.getObjectData(); - String name = ole.getInstanceName(); - switch (name == null ? "" : name) { - case "Worksheet": - //read xls - handleWorkbook(data, name, oleIdx); - break; - case "Document": - //read the word document - handleDocument(data, name, oleIdx); - break; - default: - handleUnknown(data, ole.getProgId(), oleIdx); - break; - } - } - - //Pictures - else if (shape instanceof HSLFPictureShape) { - picIdx++; - HSLFPictureShape p = (HSLFPictureShape) shape; - HSLFPictureData data = p.getPictureData(); - handlePicture(data, picIdx); + handleShape((HSLFObjectShape) shape, ++oleIdx); + } else if (shape instanceof HSLFPictureShape) { + handlePicture((HSLFPictureShape) shape, ++picIdx); } } } } } + private static void handleShape(HSLFObjectShape ole, int oleIdx) throws IOException { + HSLFObjectData data = ole.getObjectData(); + String name = ole.getInstanceName(); + switch (name == null ? "" : name) { + case "Worksheet": + //read xls + handleWorkbook(data, name, oleIdx); + break; + case "Document": + //read the word document + handleDocument(data, name, oleIdx); + break; + default: + handleUnknown(data, ole.getProgId(), oleIdx); + break; + } + + } + private static void handleWorkbook(HSLFObjectData data, String name, int oleIdx) throws IOException { try (InputStream is = data.getInputStream(); HSSFWorkbook wb = new HSSFWorkbook(is); @@ -126,7 +124,8 @@ public final class DataExtraction { } } - private static void handlePicture(HSLFPictureData data, int picIdx) throws IOException { + private static void handlePicture(HSLFPictureShape p, int picIdx) throws IOException { + HSLFPictureData data = p.getPictureData(); String ext = data.getType().extension; try (FileOutputStream out = new FileOutputStream("pict-" + picIdx + ext)) { out.write(data.getData()); diff --git a/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java b/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java index 963033ad12..75ccf0121e 100644 --- a/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java +++ b/src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java @@ -42,7 +42,7 @@ public final class Graphics2DDemo { try (HSLFSlideShow ppt = new HSLFSlideShow(); FileOutputStream out = new FileOutputStream("hslf-graphics.ppt")) { //bar chart data. The first value is the bar color, the second is the width - Object[] def = new Object[]{ + Object[] def = { Color.yellow, 40, Color.green, 60, Color.gray, 30, diff --git a/src/examples/src/org/apache/poi/hsmf/examples/Msg2txt.java b/src/examples/src/org/apache/poi/hsmf/examples/Msg2txt.java index 83d4701289..010e711557 100644 --- a/src/examples/src/org/apache/poi/hsmf/examples/Msg2txt.java +++ b/src/examples/src/org/apache/poi/hsmf/examples/Msg2txt.java @@ -31,22 +31,21 @@ import org.apache.poi.hsmf.exceptions.ChunkNotFoundException; * Reads one or several Outlook MSG files and for each of them creates * a text file from available chunks and a directory that contains * attachments. - * - * @author Bruno Girin */ +@SuppressWarnings({"java:S106","java:S4823"}) public class Msg2txt { - + /** * The stem used to create file names for the text file and the directory * that contains the attachments. */ private String fileNameStem; - + /** * The Outlook MSG file being processed. */ private MAPIMessage msg; - + public Msg2txt(String fileName) throws IOException { fileNameStem = fileName; if(fileNameStem.endsWith(".msg") || fileNameStem.endsWith(".MSG")) { @@ -54,10 +53,10 @@ public class Msg2txt { } msg = new MAPIMessage(fileName); } - + /** * Processes the message. - * + * * @throws IOException if an exception occurs while writing the message out */ public void processMessage() throws IOException { @@ -114,7 +113,7 @@ public class Msg2txt { } } } - + /** * Processes a single attachment: reads it from the Outlook MSG file and * writes it to disk as an individual file. @@ -123,22 +122,22 @@ public class Msg2txt { * @param dir the directory in which to write the attachment file * @throws IOException when any of the file operations fails */ - public void processAttachment(AttachmentChunks attachment, + public void processAttachment(AttachmentChunks attachment, File dir) throws IOException { String fileName = attachment.getAttachFileName().toString(); if(attachment.getAttachLongFileName() != null) { fileName = attachment.getAttachLongFileName().toString(); } - + File f = new File(dir, fileName); try (OutputStream fileOut = new FileOutputStream(f)) { fileOut.write(attachment.getAttachData().getValue()); } } - + /** * Processes the list of arguments as a list of names of Outlook MSG files. - * + * * @param args the list of MSG files to process */ public static void main(String[] args) { diff --git a/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java b/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java index a4897d18f0..da06079c32 100644 --- a/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java +++ b/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java @@ -43,7 +43,6 @@ import org.apache.poi.hssf.record.LabelSSTRecord; import org.apache.poi.hssf.record.NoteRecord; import org.apache.poi.hssf.record.NumberRecord; import org.apache.poi.hssf.record.RKRecord; -import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.SSTRecord; import org.apache.poi.hssf.record.StringRecord; import org.apache.poi.hssf.usermodel.HSSFWorkbook; @@ -54,6 +53,7 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem; * EventModel code to ensure it outputs all columns and rows. * @author Nick Burch */ +@SuppressWarnings({"java:S106","java:S4823"}) public class XLS2CSVmra implements HSSFListener { private int minColumns; private POIFSFileSystem fs; @@ -72,7 +72,7 @@ public class XLS2CSVmra implements HSSFListener { // Records we pick up as we process private SSTRecord sstRecord; private FormatTrackingHSSFListener formatListener; - + /** So we known which sheet we're on */ private int sheetIndex = -1; private BoundSheetRecord[] orderedBSRs; @@ -149,7 +149,7 @@ public class XLS2CSVmra implements HSSFListener { if(workbookBuildingListener != null && stubWorkbook == null) { stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook(); } - + // Output the worksheet name // Works by ordering the BSRs by the location of // their BOFRecords, and then knowing that we @@ -159,7 +159,7 @@ public class XLS2CSVmra implements HSSFListener { orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords); } output.println(); - output.println( + output.println( orderedBSRs[sheetIndex].getSheetname() + " [" + (sheetIndex+1) + "]:" ); diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java index abef3e884f..38e2fe6f51 100644 --- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java +++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java @@ -18,873 +18,6 @@ package org.apache.poi.hssf.usermodel.examples; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; - -import org.apache.poi.hssf.usermodel.HSSFClientAnchor; -import org.apache.poi.hssf.usermodel.HSSFPatriarch; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.IOUtils; - - -/** - * Demonstrates how to add an image to a worksheet and set that image's size - * to a specific number of milimetres irrespective of the width of the columns - * or height of the rows. Overridden methods are provided so that the location - * of the image - the cells row and column co-ordinates that define the top - * left hand corners of the image - can be identified either in the familiar - * Excel manner - A1 for instance - or using POI's methodolody of a column and - * row index where 0, 0 would indicate cell A1. - * - * The best way to make use of these techniques is to delay adding the image to - * the sheet until all other work has been completed. That way, the sizes of - * all rows and columns will have been adjusted - assuming that step was - * necessary. Even though the anchors type is set to prevent the image moving - * or re-sizing, this setting does not have any effect until the sheet is being - * viewed using the Excel application. - * - * The key to the process is the HSSFClientAnchor class. It accepts eight - * parameters that define, in order; - * - * * How far - in terms of co-ordinate position - the image should be inset - * from the left hand border of a cell. - * * How far - in terms of co-ordinate positions - the image should be inset - * from the from the top of the cell. - * * How far - in terms of co-ordinate positions - the right hand edge of - * the image should protrude into a cell (measured from the cell's left hand - * edge to the image's right hand edge). - * * How far - in terms of co-ordinate positions - the bottm edge of the - * image should protrude into a row (measured from the cell's top edge to - * the image's bottom edge). - * * The index of the column that contains the cell whose top left hand - * corner should be aligned with the top left hand corner of the image. - * * The index of the row that contains the cell whose top left hand corner - * should be aligned with the image's top left hand corner. - * * The index of the column that contains the cell whose top left hand - * corner should be aligned with the image's bottom right hand corner - * * The index number of the row that contains the cell whose top left - * hand corner should be aligned with the images bottom right hand corner. - * - * It can be used to add an image into cell A1, for example, in the following - * manner; - * - * HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, - * (short)0, 0, (short)1, 1); - * - * The final four parameters determine that the top left hand corner should be - * aligned with the top left hand corner of cell A1 and it's bottom right - * hand corner with the top left hand corner of cell B2. Think of the image as - * being stretched so that it's top left hand corner is aligned with the top - * left hand corner of cell A1 and it's bottom right hand corner is aligned with - * the top left hand corner of cell B1. Interestingly, this would also produce - * the same results; - * - * anchor = new HSSFClientAnchor(0, 0, 1023, 255, - * (short)0, 0, (short)0, 0); - * - * Note that the final four parameters all contain the same value and seem to - * indicate that the images top left hand corner is aligned with the top left - * hand corner of cell A1 and that it's bottom right hand corner is also - * aligned with the top left hand corner of cell A1. Yet, running this code - * would see the image fully occupying cell A1. That is the result of the - * values passed to parameters three and four; these I have referred to as - * determing the images co-ordinates within the cell. They indicate that the - * image should occupy - in order - the full width of the column and the full - * height of the row. - * - * The co-ordinate values shown are the maxima; and they are independent of - * row height/column width and of the font used. Passing 255 will always result - * in the image occupying the full height of the row and passing 1023 will - * always result in the image occupying the full width of the column. They help - * in situations where an image is larger than a column/row and must overlap - * into the next column/row. Using them does mean, however, that it is often - * necessary to perform conversions between Excel's characters units, points, - * pixels and millimetres in order to establish how many rows/columns an image - * should occupy and just what the varous insets ought to be. - * - * Note that the first two parameters of the HSSFClientAchor classes constructor - * are not made use of in the code that follows. It would be fairly trivial - * however to extend these example further and provide methods that would centre - * an image within a cell or allow the user to specify that a plain border a - * fixed number of millimetres wide should wrap around the image. Those first - * two parameters would make this sort of functionality perfectly possible. - * - * Owing to the various conversions used, the actual size of the image may vary - * from that required; testing has so far found this to be in the region of - * plus or minus two millimetres. Most likely by modifying the way the - * calculations are performed - possibly using double(s) throughout and - * rounding the values at the correct point - it is likely that these errors - * could be reduced or removed. - * - * A note concerning Excels' image resizing behaviour. The HSSFClientAnchor - * class contains a method called setAnchorType(int) which can be used to - * determine how Excel will resize an image in reponse to the user increasing - * or decreasing the dimensions of the cell containing the image. There are - * three values that can be passed to this method; 0 = To move and size the - * image with the cell, 2 = To move but don't size the image with the cell, - * 3 = To prevent the image from moving or being resized along with the cell. If - * an image is inserted using this class and placed into a single cell then if - * the setAnchorType(int) method is called and a value of either 0 or 2 passed - * to it, the resultant resizing behaviour may be a surprise. The image will not - * grow in size of the column is made wider or the row higher but it will shrink - * if the columns width or rows height are reduced. - * - * @author Mark Beardsley [msb at apache.org] - * @version 1.00 5th August 2009. - */ -public class AddDimensionedImage { - - // Four constants that determine how - and indeed whether - the rows - // and columns an image may overlie should be expanded to accommodate that - // image. - // Passing EXPAND_ROW will result in the height of a row being increased - // to accommodate the image if it is not already larger. The image will - // be layed across one or more columns. - // Passing EXPAND_COLUMN will result in the width of the column being - // increased to accommodate the image if it is not already larger. The image - // will be layed across one or many rows. - // Passing EXPAND_ROW_AND_COLUMN will result in the height of the row - // bing increased along with the width of the column to accomdate the - // image if either is not already larger. - // Passing OVERLAY_ROW_AND_COLUMN will result in the image being layed - // over one or more rows and columns. No row or column will be resized, - // instead, code will determine how many rows and columns the image should - // overlie. - public static final int EXPAND_ROW = 1; - public static final int EXPAND_COLUMN = 2; - public static final int EXPAND_ROW_AND_COLUMN = 3; - public static final int OVERLAY_ROW_AND_COLUMN = 7; - - /** - * Add an image to a worksheet. - * - * @param cellNumber A String that contains the location of the cell whose - * top left hand corner should be aligned with the top - * left hand corner of the image; for example "A1", "A2" - * etc. This is to support the familiar Excel syntax. - * Whilst images are are not actually inserted into cells - * this provides a convenient method of indicating where - * the image should be positioned on the sheet. - * @param sheet A reference to the sheet that contains the cell referenced - * above. - * @param imageFile A String that encapsulates the name of and path to - * the image that is to be 'inserted into' the sheet. - * @param reqImageWidthMM A primitive double that contains the required - * width of the image in millimetres. - * @param reqImageHeightMM A primitive double that contains the required - * height of the image in millimetres. - * @param resizeBehaviour A primitive int whose value will determine how - * the code should react if the image is larger than - * the cell referenced by the cellNumber parameter. - * Four constants are provided to determine what - * should happen; - * AddDimensionedImage.EXPAND_ROW - * AddDimensionedImage.EXPAND_COLUMN - * AddDimensionedImage.EXPAND_ROW_AND_COLUMN - * AddDimensionedImage.OVERLAY_ROW_AND_COLUMN - * @throws java.io.FileNotFoundException If the file containing the image - * cannot be located. - * @throws java.io.IOException If a problem occurs whilst reading the file - * of image data. - * @throws java.lang.IllegalArgumentException If an invalid value is passed - * to the resizeBehaviour - * parameter. - */ - public void addImageToSheet(String cellNumber, HSSFSheet sheet, - String imageFile, double reqImageWidthMM, double reqImageHeightMM, - int resizeBehaviour) throws IOException, IllegalArgumentException { - // Convert the String into column and row indices then chain the - // call to the overridden addImageToSheet() method. - CellReference cellRef = new CellReference(cellNumber); - this.addImageToSheet(cellRef.getCol(), cellRef.getRow(), sheet, - imageFile, reqImageWidthMM, reqImageHeightMM,resizeBehaviour); - } - - /** - * Add an image to a worksheet. - * - * @param colNumber A primitive int that contains the index number of a - * column on the worksheet; POI column indices are zero - * based. Together with the rowNumber parameter's value, - * this parameter identifies a cell on the worksheet. The - * image's top left hand corner will be aligned with the - * top left hand corner of this cell. - * @param rowNumber A primtive int that contains the index number of a row - * on the worksheet; POI row indices are zero based. - * Together with the rowNumber parameter's value, this - * parameter identifies a cell on the worksheet. The - * image's top left hand corner will be aligned with the - * top left hand corner of this cell. - * @param sheet A reference to the sheet that contains the cell identified - * by the two parameters above. - * @param imageFile A String that encapsulates the name of and path to - * the image that is to be 'inserted into' the sheet. - * @param reqImageWidthMM A primitive double that contains the required - * width of the image in millimetres. - * @param reqImageHeightMM A primitive double that contains the required - * height of the image in millimetres. - * @param resizeBehaviour A primitive int whose value will determine how - * the code should react if the image is larger than - * the cell referenced by the colNumber and - * rowNumber parameters. Four constants are provided - * to determine what should happen; - * AddDimensionedImage.EXPAND_ROW - * AddDimensionedImage.EXPAND_COLUMN - * AddDimensionedImage.EXPAND_ROW_AND_COLUMN - * AddDimensionedImage.OVERLAY_ROW_AND_COLUMN - * @throws java.io.FileNotFoundException If the file containing the image - * cannot be located. - * @throws java.io.IOException If a problem occurs whilst reading the file - * of image data. - * @throws java.lang.IllegalArgumentException If an invalid value is passed - * to the resizeBehaviour - * parameter. - */ - private void addImageToSheet(int colNumber, int rowNumber, HSSFSheet sheet, - String imageFile, double reqImageWidthMM, double reqImageHeightMM, - int resizeBehaviour) throws FileNotFoundException, IOException, - IllegalArgumentException { - HSSFClientAnchor anchor; - HSSFPatriarch patriarch; - ClientAnchorDetail rowClientAnchorDetail; - ClientAnchorDetail colClientAnchorDetail; - - // Validate the resizeBehaviour parameter. - if((resizeBehaviour != AddDimensionedImage.EXPAND_COLUMN) && - (resizeBehaviour != AddDimensionedImage.EXPAND_ROW) && - (resizeBehaviour != AddDimensionedImage.EXPAND_ROW_AND_COLUMN) && - (resizeBehaviour != AddDimensionedImage.OVERLAY_ROW_AND_COLUMN)) { - throw new IllegalArgumentException("Invalid value passed to the " + - "resizeBehaviour parameter of AddDimensionedImage.addImageToSheet()"); - } - - // Call methods to calculate how the image and sheet should be - // manipulated to accommodate the image; columns and then rows. - colClientAnchorDetail = this.fitImageToColumns(sheet, colNumber, - reqImageWidthMM, resizeBehaviour); - rowClientAnchorDetail = this.fitImageToRows(sheet, rowNumber, - reqImageHeightMM, resizeBehaviour); - - // Having determined if and how to resize the rows, columns and/or the - // image, create the HSSFClientAnchor object to position the image on - // the worksheet. Note how the two ClientAnchorDetail records are - // interrogated to recover the row/column co-ordinates and any insets. - // The first two parameters are not used currently but could be if the - // need arose to extend the functionality of this code by adding the - // ability to specify that a clear 'border' be placed around the image. - int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0; - short col1 = 0, col2 = 0, row1 = 0, row2 = 0; - if (colClientAnchorDetail != null) { - dx2 = colClientAnchorDetail.getInset(); - col1 = (short)colClientAnchorDetail.getFromIndex(); - col2 = (short)colClientAnchorDetail.getToIndex(); - } - if (rowClientAnchorDetail != null) { - dy2 = rowClientAnchorDetail.getInset(); - row1 = (short)rowClientAnchorDetail.getFromIndex(); - row2 = (short)rowClientAnchorDetail.getToIndex(); - } - anchor = new HSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2); - - // For now, set the anchor type to do not move or resize the - // image as the size of the row/column is adjusted. This could easilly - // become another parameter passed to the method. - //anchor.setAnchorType(HSSFClientAnchor.DONT_MOVE_AND_RESIZE); - anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE); - - // Now, add the picture to the workbook. Note that the type is assumed - // to be a JPEG/JPG, this could easily (and should) be parameterised - // however. - //int index = sheet.getWorkbook().addPicture(this.imageToBytes(imageFile), - // HSSFWorkbook.PICTURE_TYPE_JPEG); - int index = sheet.getWorkbook().addPicture(this.imageToBytes(imageFile), Workbook.PICTURE_TYPE_PNG); - - // Get the drawing patriarch and create the picture. - patriarch = sheet.createDrawingPatriarch(); - patriarch.createPicture(anchor, index); - } - - /** - * Determines whether the sheets columns should be re-sized to accommodate - * the image, adjusts the columns width if necessary and creates then - * returns a ClientAnchorDetail object that facilitates construction of - * an HSSFClientAnchor that will fix the image on the sheet and establish - * it's size. - * - * @param sheet A reference to the sheet that will 'contain' the image. - * @param colNumber A primtive int that contains the index number of a - * column on the sheet. - * @param reqImageWidthMM A primtive double that contains the required - * width of the image in millimetres - * @param resizeBehaviour A primitve int whose value will indicate how the - * width of the column should be adjusted if the - * required width of the image is greater than the - * width of the column. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the column containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number column containing the cell whose top - * left hand corner also defines the bottom right hand corner of - * the image and an inset that determines how far the right hand - * edge of the image can protrude into the next column - expressed - * as a specific number of co-ordinate positions. - */ - private ClientAnchorDetail fitImageToColumns(HSSFSheet sheet, int colNumber, - double reqImageWidthMM, int resizeBehaviour) { - - double colWidthMM; - double colCoordinatesPerMM; - int pictureWidthCoordinates; - ClientAnchorDetail colClientAnchorDetail = null; - - // Get the colum's width in millimetres - colWidthMM = ConvertImageUnits.widthUnits2Millimetres( - (short)sheet.getColumnWidth(colNumber)); - - // Check that the column's width will accommodate the image at the - // required dimension. If the width of the column is LESS than the - // required width of the image, decide how the application should - // respond - resize the column or overlay the image across one or more - // columns. - if(colWidthMM < reqImageWidthMM) { - - // Should the column's width simply be expanded? - if((resizeBehaviour == AddDimensionedImage.EXPAND_COLUMN) || - (resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) { - // Set the width of the column by converting the required image - // width from millimetres into Excel's column width units. - sheet.setColumnWidth(colNumber, - ConvertImageUnits.millimetres2WidthUnits(reqImageWidthMM)); - // To make the image occupy the full width of the column, convert - // the required width of the image into co-ordinates. This value - // will become the inset for the ClientAnchorDetail class that - // is then instantiated. - colWidthMM = reqImageWidthMM; - colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / - colWidthMM; - pictureWidthCoordinates = (int)(reqImageWidthMM * colCoordinatesPerMM); - colClientAnchorDetail = new ClientAnchorDetail(colNumber, - colNumber, pictureWidthCoordinates); - } - // If the user has chosen to overlay both rows and columns or just - // to expand ONLY the size of the rows, then calculate how to lay - // the image out across one or more columns. - else if ((resizeBehaviour == AddDimensionedImage.OVERLAY_ROW_AND_COLUMN) || - (resizeBehaviour == AddDimensionedImage.EXPAND_ROW)) { - colClientAnchorDetail = this.calculateColumnLocation(sheet, - colNumber, reqImageWidthMM); - } - } - // If the column is wider than the image. - else { - // Mow many co-ordinate positions are there per millimetre? - colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / - colWidthMM; - // Given the width of the image, what should be it's co-ordinate? - pictureWidthCoordinates = (int)(reqImageWidthMM * colCoordinatesPerMM); - colClientAnchorDetail = new ClientAnchorDetail(colNumber, - colNumber, pictureWidthCoordinates); - } - return(colClientAnchorDetail); - } - - /** - * Determines whether the sheet's row should be re-sized to accommodate - * the image, adjusts the rows height if necessary and creates then - * returns a ClientAnchorDetail object that facilitates construction of - * an HSSFClientAnchor that will fix the image on the sheet and establish - * it's size. - * - * @param sheet A reference to the sheet that will 'contain' the image. - * @param rowNumber A primtive int that contains the index number of a - * row on the sheet. - * @param reqImageHeightMM A primtive double that contains the required - * height of the image in millimetres - * @param resizeBehaviour A primitve int whose value will indicate how the - * height of the row should be adjusted if the - * required height of the image is greater than the - * height of the row. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the row containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number of the row containing the cell whose - * top left hand corner also defines the bottom right hand - * corner of the image and an inset that determines how far the - * bottom edge of the image can protrude into the next (lower) - * row - expressed as a specific number of co-ordinate positions. - */ - private ClientAnchorDetail fitImageToRows(HSSFSheet sheet, int rowNumber, - double reqImageHeightMM, int resizeBehaviour) { - double rowCoordinatesPerMM; - int pictureHeightCoordinates; - ClientAnchorDetail rowClientAnchorDetail = null; - - // Get the row and it's height - HSSFRow row = sheet.getRow(rowNumber); - if(row == null) { - // Create row if it does not exist. - row = sheet.createRow(rowNumber); - } - - // Get the row's height in millimetres - double rowHeightMM = row.getHeightInPoints() / ConvertImageUnits.POINTS_PER_MILLIMETRE; - - // Check that the row's height will accommodate the image at the required - // dimensions. If the height of the row is LESS than the required height - // of the image, decide how the application should respond - resize the - // row or overlay the image across a series of rows. - if(rowHeightMM < reqImageHeightMM) { - if((resizeBehaviour == AddDimensionedImage.EXPAND_ROW) || - (resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) { - row.setHeightInPoints((float)(reqImageHeightMM * - ConvertImageUnits.POINTS_PER_MILLIMETRE)); - rowHeightMM = reqImageHeightMM; - rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / - rowHeightMM; - pictureHeightCoordinates = (int)(reqImageHeightMM * rowCoordinatesPerMM); - rowClientAnchorDetail = new ClientAnchorDetail(rowNumber, - rowNumber, pictureHeightCoordinates); - } - // If the user has chosen to overlay both rows and columns or just - // to expand ONLY the size of the columns, then calculate how to lay - // the image out ver one or more rows. - else if((resizeBehaviour == AddDimensionedImage.OVERLAY_ROW_AND_COLUMN) || - (resizeBehaviour == AddDimensionedImage.EXPAND_COLUMN)) { - rowClientAnchorDetail = this.calculateRowLocation(sheet, - rowNumber, reqImageHeightMM); - } - } - // Else, if the image is smaller than the space available - else { - rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / - rowHeightMM; - pictureHeightCoordinates = (int)(reqImageHeightMM * rowCoordinatesPerMM); - rowClientAnchorDetail = new ClientAnchorDetail(rowNumber, - rowNumber, pictureHeightCoordinates); - } - return(rowClientAnchorDetail); - } - - /** - * If the image is to overlie more than one column, calculations need to be - * performed to determine how many columns and whether the image will - * overlie just a part of one column in order to be presented at the - * required size. - * - * @param sheet The sheet that will 'contain' the image. - * @param startingColumn A primitive int whose value is the index of the - * column that contains the cell whose top left hand - * corner should be aligned with the top left hand - * corner of the image. - * @param reqImageWidthMM A primitive double whose value will indicate the - * required width of the image in millimetres. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the column containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number column containing the cell whose top - * left hand corner also defines the bottom right hand corner of - * the image and an inset that determines how far the right hand - * edge of the image can protrude into the next column - expressed - * as a specific number of co-ordinate positions. - */ - private ClientAnchorDetail calculateColumnLocation(HSSFSheet sheet, - int startingColumn, - double reqImageWidthMM) { - ClientAnchorDetail anchorDetail; - double totalWidthMM = 0.0D; - double colWidthMM = 0.0D; - double overlapMM; - double coordinatePositionsPerMM; - int toColumn = startingColumn; - int inset; - - // Calculate how many columns the image will have to - // span in order to be presented at the required size. - while(totalWidthMM < reqImageWidthMM) { - colWidthMM = ConvertImageUnits.widthUnits2Millimetres( - (short)(sheet.getColumnWidth(toColumn))); - // Note use of the cell border width constant. Testing with an image - // declared to fit exactly into one column demonstrated that it's - // width was greater than the width of the column the POI returned. - // Further, this difference was a constant value that I am assuming - // related to the cell's borders. Either way, that difference needs - // to be allowed for in this calculation. - totalWidthMM += (colWidthMM + ConvertImageUnits.CELL_BORDER_WIDTH_MILLIMETRES); - toColumn++; - } - // De-crement by one the last column value. - toColumn--; - // Highly unlikely that this will be true but, if the width of a series - // of columns is exactly equal to the required width of the image, then - // simply build a ClientAnchorDetail object with an inset equal to the - // total number of co-ordinate positions available in a column, a - // from column co-ordinate (top left hand corner) equal to the value - // of the startingColumn parameter and a to column co-ordinate equal - // to the toColumn variable. - // - // Convert both values to ints to perform the test. - if((int)totalWidthMM == (int)reqImageWidthMM) { - // A problem could occur if the image is sized to fit into one or - // more columns. If that occurs, the value in the toColumn variable - // will be in error. To overcome this, there are two options, to - // ibcrement the toColumn variable's value by one or to pass the - // total number of co-ordinate positions to the third paramater - // of the ClientAnchorDetail constructor. For no sepcific reason, - // the latter option is used below. - anchorDetail = new ClientAnchorDetail(startingColumn, - toColumn, ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS); - } - // In this case, the image will overlap part of another column and it is - // necessary to calculate just how much - this will become the inset - // for the ClientAnchorDetail object. - else { - // Firstly, claculate how much of the image should overlap into - // the next column. - overlapMM = reqImageWidthMM - (totalWidthMM - colWidthMM); - - // When the required size is very close indded to the column size, - // the calcaulation above can produce a negative value. To prevent - // problems occuring in later caculations, this is simply removed - // be setting the overlapMM value to zero. - if(overlapMM < 0) { - overlapMM = 0.0D; - } - - // Next, from the columns width, calculate how many co-ordinate - // positons there are per millimetre - coordinatePositionsPerMM = colWidthMM == 0 ? 0 - : ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / colWidthMM; - // From this figure, determine how many co-ordinat positions to - // inset the left hand or bottom edge of the image. - inset = (int)(coordinatePositionsPerMM * overlapMM); - - // Now create the ClientAnchorDetail object, setting the from and to - // columns and the inset. - anchorDetail = new ClientAnchorDetail(startingColumn, toColumn, inset); - } - return(anchorDetail); - } - - /** - * If the image is to overlie more than one rows, calculations need to be - * performed to determine how many rows and whether the image will - * overlie just a part of one row in order to be presented at the - * required size. - * - * @param sheet The sheet that will 'contain' the image. - * @param startingRow A primitive int whose value is the index of the row - * that contains the cell whose top left hand corner - * should be aligned with the top left hand corner of - * the image. - * @param reqImageHeightMM A primitive double whose value will indicate the - * required height of the image in millimetres. - * @return An instance of the ClientAnchorDetail class that will contain - * the index number of the row containing the cell whose top - * left hand corner also defines the top left hand corner of the - * image, the index number of the row containing the cell whose top - * left hand corner also defines the bottom right hand corner of - * the image and an inset that determines how far the bottom edge - * can protrude into the next (lower) row - expressed as a specific - * number of co-ordinate positions. - */ - private ClientAnchorDetail calculateRowLocation(HSSFSheet sheet, - int startingRow, double reqImageHeightMM) { - ClientAnchorDetail clientAnchorDetail; - HSSFRow row; - double rowHeightMM = 0.0D; - double totalRowHeightMM = 0.0D; - double overlapMM; - double rowCoordinatesPerMM; - int toRow = startingRow; - int inset; - - // Step through the rows in the sheet and accumulate a total of their - // heights. - while(totalRowHeightMM < reqImageHeightMM) { - row = sheet.getRow(toRow); - // Note, if the row does not already exist on the sheet then create - // it here. - if(row == null) { - row = sheet.createRow(toRow); - } - // Get the row's height in millimetres and add to the running total. - rowHeightMM = row.getHeightInPoints() / ConvertImageUnits.POINTS_PER_MILLIMETRE; - totalRowHeightMM += rowHeightMM; - toRow++; - } - // Owing to the way the loop above works, the rowNumber will have been - // incremented one row too far. Undo that here. - toRow--; - // Check to see whether the image should occupy an exact number of - // rows. If so, build the ClientAnchorDetail record to point - // to those rows and with an inset of the total number of co-ordinate - // position in the row. - // - // To overcome problems that can occur with comparing double values for - // equality, cast both to int(s) to truncate the value; VERY crude and - // I do not really like it!! - if((int)totalRowHeightMM == (int)reqImageHeightMM) { - clientAnchorDetail = new ClientAnchorDetail(startingRow, toRow, - ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS); - } - else { - // Calculate how far the image will project into the next row. Note - // that the height of the last row assessed is subtracted from the - // total height of all rows assessed so far. - overlapMM = reqImageHeightMM - (totalRowHeightMM - rowHeightMM); - - // To prevent an exception being thrown when the required width of - // the image is very close indeed to the column size. - if(overlapMM < 0) { - overlapMM = 0.0D; - } - - rowCoordinatesPerMM = rowHeightMM == 0 ? 0 - : ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / rowHeightMM; - inset = (int)(overlapMM * rowCoordinatesPerMM); - clientAnchorDetail = new ClientAnchorDetail(startingRow, toRow, inset); - } - return(clientAnchorDetail); - } - - /** - * Loads - reads in and converts into an array of byte(s) - an image from - * a named file. - * - * Note: this method should be modified so that the type of the image may - * also be passed to it. Currently, it assumes that all images are - * JPG/JPEG(s). - * - * @param imageFilename A String that encapsulates the path to and name - * of the file that contains the image which is to be - * 'loaded'. - * @return An array of type byte that contains the raw data of the named - * image. - * @throws java.io.FileNotFoundException Thrown if it was not possible to - * open the specified file. - * @throws java.io.IOException Thrown if reading the file failed or was - * interrupted. - */ - private byte[] imageToBytes(String imageFilename) throws IOException { - File imageFile = new File(imageFilename); - try (FileInputStream fis = new FileInputStream(imageFile)) { - return IOUtils.toByteArray(fis); - } - } - - /** - * The main entry point to the program. It contains code that demonstrates - * one way to use the program. - * - * Note, the code is not restricted to use on new workbooks only. If an - * image is to be inserted into an existing workbook. just open that - * workbook, gat a reference to a sheet and pass that; - * - * AddDimensionedImage addImage = new AddDimensionedImage(); - * - * File file = new File("....... Existing Workbook ......."); - * FileInputStream fis = new FileInputStream(file); - * HSSFWorkbook workbook = new HSSFWorkbook(fis); - * HSSFSheet sheet = workbook.getSheetAt(0); - * addImage.addImageToSheet("C3", sheet, "image.jpg", 30, 20, - * AddDimensionedImage.EXPAND.ROW); - * - * @param args the command line arguments - */ - public static void main(String[] args) throws IOException { - if(args.length < 2){ - System.err.println("Usage: AddDimensionedImage imageFile outputFile"); - return; - } - String imageFile = args[0]; - String outputFile = args[1]; - - try (HSSFWorkbook workbook = new HSSFWorkbook()) { - HSSFSheet sheet = workbook.createSheet("Picture Test"); - new AddDimensionedImage().addImageToSheet("A1", sheet, - imageFile, 125, 125, - AddDimensionedImage.EXPAND_ROW_AND_COLUMN); - try (FileOutputStream fos = new FileOutputStream(outputFile)) { - workbook.write(fos); - } - } - } - - /** - * The HSSFClientAnchor class accepts eight parameters. In order, these are; - * - * * How far the left hand edge of the image is inset from the left hand - * edge of the cell - * * How far the top edge of the image is inset from the top of the cell - * * How far the right hand edge of the image is inset from the left - * hand edge of the cell - * * How far the bottom edge of the image is inset from the top of the - * cell. - * * Together, parameters five and six determine the column and row - * co-ordinates of the cell whose top left hand corner will be aligned - * with the image's top left hand corner. - * * Together, parameter seven and eight determine the column and row - * co-ordinates of the cell whose top left hand corner will be aligned - * with the images bottom right hand corner. - * - * An instance of the ClientAnchorDetail class provides three of the eight - * parameters, one of the co-ordinates for the images top left hand corner, - * one of the co-ordinates for the images bottom right hand corner and - * either how far the image should be inset from the top or the left hand - * edge of the cell. - * - * @author Mark Beardsley [mas at apache.org] - * @version 1.00 5th August 2009. - */ - public static class ClientAnchorDetail { - - private int fromIndex; - private int toIndex; - private int inset; - - /** - * Create a new instance of the ClientAnchorDetail class using the - * following parameters. - * - * @param fromIndex A primitive int that contains one of the - * co-ordinates (row or column index) for the top left - * hand corner of the image. - * @param toIndex A primitive int that contains one of the - * co-ordinates (row or column index) for the bottom - * right hand corner of the image. - * @param inset A primitive int that contains a value which indicates - * how far the image should be inset from the top or the - * left hand edge of a cell. - */ - public ClientAnchorDetail(int fromIndex, int toIndex, int inset) { - this.fromIndex = fromIndex; - this.toIndex = toIndex; - this.inset = inset; - } - - /** - * Get one of the number of the column or row that contains the cell - * whose top left hand corner will be aligned with the top left hand - * corner of the image. - * - * @return The value - row or column index - for one of the co-ordinates - * of the top left hand corner of the image. - */ - public int getFromIndex() { - return(this.fromIndex); - } - - /** - * Get one of the number of the column or row that contains the cell - * whose top left hand corner will be aligned with the bottom righ hand - * corner of the image. - * - * @return The value - row or column index - for one of the co-ordinates - * of the bottom right hand corner of the image. - */ - public int getToIndex() { - return(this.toIndex); - } - - /** - * Get the image's offset from the edge of a cell. - * - * @return How far either the right hand or bottom edge of the image is - * inset from the left hand or top edge of a cell. - */ - public int getInset() { - return(this.inset); - } - } - - /** - * Utility methods used to convert Excel's character based column and row - * size measurements into pixels and/or millimetres. The class also contains - * various constants that are required in other calculations. - * - * @author xio[darjino@hotmail.com] - * @version 1.01 30th July 2009. - * Added by Mark Beardsley [msb at apache.org]. - * Additional constants. - * widthUnits2Millimetres() and millimetres2Units() methods. - */ - private static final class ConvertImageUnits { - - // Each cell conatins a fixed number of co-ordinate points; this number - // does not vary with row height or column width or with font. These two - // constants are defined below. - public static final int TOTAL_COLUMN_COORDINATE_POSITIONS = 1023; // MB - public static final int TOTAL_ROW_COORDINATE_POSITIONS = 255; // MB - // Cnstants that defines how many pixels and points there are in a - // millimetre. These values are required for the conversion algorithm. - public static final double PIXELS_PER_MILLIMETRES = 3.78; // MB - public static final double POINTS_PER_MILLIMETRE = 2.83; // MB - // The column width returned by HSSF and the width of a picture when - // positioned to exactly cover one cell are different by almost exactly - // 2mm - give or take rounding errors. This constant allows that - // additional amount to be accounted for when calculating how many - // celles the image ought to overlie. - public static final double CELL_BORDER_WIDTH_MILLIMETRES = 2.0D; // MB - public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256; - public static final int UNIT_OFFSET_LENGTH = 7; - private static final int[] UNIT_OFFSET_MAP = new int[] - { 0, 36, 73, 109, 146, 182, 219 }; - - /** - * pixel units to excel width units(units of 1/256th of a character width) - */ - public static short pixel2WidthUnits(int pxs) { - short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR * - (pxs / UNIT_OFFSET_LENGTH)); - widthUnits += UNIT_OFFSET_MAP[(pxs % UNIT_OFFSET_LENGTH)]; - return widthUnits; - } - - /** - * excel width units(units of 1/256th of a character width) to pixel - * units. - */ - public static int widthUnits2Pixel(short widthUnits) { - int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR) - * UNIT_OFFSET_LENGTH; - int offsetWidthUnits = widthUnits % EXCEL_COLUMN_WIDTH_FACTOR; - pixels += Math.round(offsetWidthUnits / - ((float) EXCEL_COLUMN_WIDTH_FACTOR / UNIT_OFFSET_LENGTH)); - return pixels; - } - - /** - * Convert Excel's width units into millimetres. - * - * @param widthUnits The width of the column or the height of the - * row in Excel's units. - * @return A primitive double that contains the columns width or rows - * height in millimetres. - */ - public static double widthUnits2Millimetres(short widthUnits) { - return(ConvertImageUnits.widthUnits2Pixel(widthUnits) / - ConvertImageUnits.PIXELS_PER_MILLIMETRES); - } - - /** - * Convert into millimetres Excel's width units.. - * - * @param millimetres A primitive double that contains the columns - * width or rows height in millimetres. - * @return A primitive int that contains the columns width or rows - * height in Excel's units. - */ - public static int millimetres2WidthUnits(double millimetres) { - return(ConvertImageUnits.pixel2WidthUnits((int)(millimetres * - ConvertImageUnits.PIXELS_PER_MILLIMETRES))); - } - } +/* Placeholder - this is now handled in the Common SS example **/ +public class AddDimensionedImage extends org.apache.poi.ss.examples.AddDimensionedImage { }
\ No newline at end of file diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/BigExample.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/BigExample.java index a1e84efba5..ef1a06b3bf 100644 --- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/BigExample.java +++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/BigExample.java @@ -96,7 +96,6 @@ public class BigExample { r.setHeight((short) 0x249); } - //r.setRowNum(( short ) rownum); // create 50 cells (0-49) (the += 2 becomes apparent later for (int cellnum = 0; cellnum < 50; cellnum += 2) { // create a numeric cell diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/EmbeddedObjects.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/EmbeddedObjects.java index cbd06c7256..7cfedc1152 100644 --- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/EmbeddedObjects.java +++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/EmbeddedObjects.java @@ -30,7 +30,10 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem; /** * Demonstrates how you can extract embedded data from a .xls file */ -public class EmbeddedObjects { +@SuppressWarnings({"java:S106","java:S4823"}) +public final class EmbeddedObjects { + private EmbeddedObjects() {} + @SuppressWarnings("unused") public static void main(String[] args) throws Exception { try ( @@ -43,23 +46,28 @@ public class EmbeddedObjects { String oleName = obj.getOLE2ClassName(); DirectoryNode dn = (obj.hasDirectoryEntry()) ? (DirectoryNode) obj.getDirectory() : null; Closeable document = null; - if (oleName.equals("Worksheet")) { - document = new HSSFWorkbook(dn, fs, false); - } else if (oleName.equals("Document")) { - document = new HWPFDocument(dn); - } else if (oleName.equals("Presentation")) { - document = new HSLFSlideShow(dn); - } else { - if (dn != null) { - // The DirectoryEntry is a DocumentNode. Examine its entries to find out what it is - for (Entry entry : dn) { - String name = entry.getName(); + switch (oleName) { + case "Worksheet": + document = new HSSFWorkbook(dn, fs, false); + break; + case "Document": + document = new HWPFDocument(dn); + break; + case "Presentation": + document = new HSLFSlideShow(dn); + break; + default: + if (dn != null) { + // The DirectoryEntry is a DocumentNode. Examine its entries to find out what it is + for (Entry entry : dn) { + String name = entry.getName(); + } + } else { + // There is no DirectoryEntry + // Recover the object's data from the HSSFObjectData instance. + byte[] objectData = obj.getObjectData(); } - } else { - // There is no DirectoryEntry - // Recover the object's data from the HSSFObjectData instance. - byte[] objectData = obj.getObjectData(); - } + break; } if (document != null) { document.close(); diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/EventExample.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/EventExample.java index 5f6945b3f2..9d3ba51bef 100644 --- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/EventExample.java +++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/EventExample.java @@ -15,22 +15,28 @@ See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - + package org.apache.poi.hssf.usermodel.examples; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; import org.apache.poi.hssf.eventusermodel.HSSFListener; import org.apache.poi.hssf.eventusermodel.HSSFRequest; -import org.apache.poi.hssf.record.*; +import org.apache.poi.hssf.record.BOFRecord; +import org.apache.poi.hssf.record.BoundSheetRecord; +import org.apache.poi.hssf.record.LabelSSTRecord; +import org.apache.poi.hssf.record.NumberRecord; +import org.apache.poi.hssf.record.RowRecord; +import org.apache.poi.hssf.record.SSTRecord; import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - /** * This example shows how to use the event API for reading a file. */ +@SuppressWarnings({"java:S106","java:S4823"}) public class EventExample implements HSSFListener { private SSTRecord sstrec; diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/HSSFReadWrite.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/HSSFReadWrite.java index 5ed9d905cf..52667d1c65 100644 --- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/HSSFReadWrite.java +++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/HSSFReadWrite.java @@ -40,8 +40,11 @@ import org.apache.poi.ss.util.CellRangeAddress; * It does contain sample API usage that may be educational to regular API * users. */ +@SuppressWarnings({"java:S106","java:S4823"}) public final class HSSFReadWrite { + private HSSFReadWrite() {} + /** * creates an {@link HSSFWorkbook} with the specified OS filename. */ diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/Hyperlinks.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/Hyperlinks.java index 4c9429c252..9189f15375 100644 --- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/Hyperlinks.java +++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/Hyperlinks.java @@ -42,11 +42,11 @@ public class Hyperlinks { //cell style for hyperlinks //by default hyperlinks are blue and underlined - HSSFCellStyle hlink_style = wb.createCellStyle(); - HSSFFont hlink_font = wb.createFont(); - hlink_font.setUnderline(Font.U_SINGLE); - hlink_font.setColor(HSSFColorPredefined.BLUE.getIndex()); - hlink_style.setFont(hlink_font); + HSSFCellStyle hlinkStyle = wb.createCellStyle(); + HSSFFont hlinkFont = wb.createFont(); + hlinkFont.setUnderline(Font.U_SINGLE); + hlinkFont.setColor(HSSFColorPredefined.BLUE.getIndex()); + hlinkStyle.setFont(hlinkFont); HSSFCell cell; HSSFSheet sheet = wb.createSheet("Hyperlinks"); @@ -57,7 +57,7 @@ public class Hyperlinks { HSSFHyperlink link = helper.createHyperlink(HyperlinkType.URL); link.setAddress("https://poi.apache.org/"); cell.setHyperlink(link); - cell.setCellStyle(hlink_style); + cell.setCellStyle(hlinkStyle); //link to a file in the current directory cell = sheet.createRow(1).createCell(0); @@ -65,7 +65,7 @@ public class Hyperlinks { link = helper.createHyperlink(HyperlinkType.FILE); link.setAddress("link1.xls"); cell.setHyperlink(link); - cell.setCellStyle(hlink_style); + cell.setCellStyle(hlinkStyle); //e-mail link cell = sheet.createRow(2).createCell(0); @@ -74,7 +74,7 @@ public class Hyperlinks { //note, if subject contains white spaces, make sure they are url-encoded link.setAddress("mailto:poi@apache.org?subject=Hyperlinks"); cell.setHyperlink(link); - cell.setCellStyle(hlink_style); + cell.setCellStyle(hlinkStyle); //link to a place in this workbook @@ -87,7 +87,7 @@ public class Hyperlinks { link = helper.createHyperlink(HyperlinkType.DOCUMENT); link.setAddress("'Target Sheet'!A1"); cell.setHyperlink(link); - cell.setCellStyle(hlink_style); + cell.setCellStyle(hlinkStyle); try (FileOutputStream out = new FileOutputStream("hssf-links.xls")) { wb.write(out); diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java index 1b25c1bd8d..b8d19039c1 100644 --- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java +++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java @@ -22,14 +22,15 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.List; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFRichTextString; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; /** * This class contains code that demonstrates how to insert plain, numbered @@ -48,6 +49,7 @@ import org.apache.poi.hssf.usermodel.HSSFRichTextString; * * @author Mark Beardsley [msb at apache.org] */ +@SuppressWarnings({"java:S106","java:S4823"}) public class InCellLists { // This character looks like a solid, black, loser case letter 'o' @@ -79,7 +81,7 @@ public class InCellLists { // whose items are neither bulleted or numbered - into that cell. row = sheet.createRow(1); cell = row.createCell(0); - ArrayList<String> listItems = new ArrayList<>(); + List<String> listItems = new ArrayList<>(); listItems.add("List Item One."); listItems.add("List Item Two."); listItems.add("List Item Three."); @@ -123,7 +125,7 @@ public class InCellLists { // to preserve order. row = sheet.createRow(4); cell = row.createCell(0); - ArrayList<MultiLevelListItem> multiLevelListItems = new ArrayList<>(); + List<MultiLevelListItem> multiLevelListItems = new ArrayList<>(); listItems = new ArrayList<>(); listItems.add("ML List Item One - Sub Item One."); listItems.add("ML List Item One - Sub Item Two."); @@ -212,7 +214,7 @@ public class InCellLists { * reference to the spreadsheet cell into which the list * will be written. */ - public void listInCell(HSSFWorkbook workbook, ArrayList<String> listItems, HSSFCell cell) { + public void listInCell(HSSFWorkbook workbook, List<String> listItems, HSSFCell cell) { StringBuilder buffer = new StringBuilder(); HSSFCellStyle wrapStyle = workbook.createCellStyle(); wrapStyle.setWrapText(true); @@ -242,7 +244,7 @@ public class InCellLists { * to calculate subsequent item numbers. */ public void numberedListInCell(HSSFWorkbook workbook, - ArrayList<String> listItems, + List<String> listItems, HSSFCell cell, int startingValue, int increment) { @@ -278,7 +280,7 @@ public class InCellLists { * will be written. */ public void bulletedListInCell(HSSFWorkbook workbook, - ArrayList<String> listItems, + List<String> listItems, HSSFCell cell) { StringBuilder buffer = new StringBuilder(); // Note that again, an HSSFCellStye object is required and that @@ -314,7 +316,7 @@ public class InCellLists { * will be written. */ public void multiLevelListInCell(HSSFWorkbook workbook, - ArrayList<MultiLevelListItem> multiLevelListItems, + List<MultiLevelListItem> multiLevelListItems, HSSFCell cell) { StringBuilder buffer = new StringBuilder(); // Note that again, an HSSFCellStye object is required and that @@ -329,13 +331,14 @@ public class InCellLists { buffer.append("\n"); // and then an ArrayList whose elements encapsulate the text // for the lower level list items. - ArrayList<String> lowerLevelItems = multiLevelListItem.getLowerLevelItems(); - if(!(lowerLevelItems == null) && !(lowerLevelItems.isEmpty())) { - for(String item : lowerLevelItems) { - buffer.append(InCellLists.TAB); - buffer.append(item); - buffer.append("\n"); - } + List<String> lowerLevelItems = multiLevelListItem.getLowerLevelItems(); + if (lowerLevelItems == null || lowerLevelItems.isEmpty()) { + continue; + } + for(String item : lowerLevelItems) { + buffer.append(InCellLists.TAB); + buffer.append(item); + buffer.append("\n"); } } // The StringBuilder's contents are the source for the contents @@ -371,7 +374,7 @@ public class InCellLists { * subsequent low level item. */ public void multiLevelNumberedListInCell(HSSFWorkbook workbook, - ArrayList<MultiLevelListItem> multiLevelListItems, + List<MultiLevelListItem> multiLevelListItems, HSSFCell cell, int highLevelStartingValue, int highLevelIncrement, @@ -393,8 +396,8 @@ public class InCellLists { buffer.append("\n"); // and then an ArrayList whose elements encapsulate the text // for the lower level list items. - ArrayList<String> lowerLevelItems = multiLevelListItem.getLowerLevelItems(); - if(!(lowerLevelItems == null) && !(lowerLevelItems.isEmpty())) { + List<String> lowerLevelItems = multiLevelListItem.getLowerLevelItems(); + if(lowerLevelItems != null && !lowerLevelItems.isEmpty()) { int lowLevelItemNumber = lowLevelStartingValue; for(String item : lowerLevelItems) { buffer.append(InCellLists.TAB); @@ -431,7 +434,7 @@ public class InCellLists { * will be written. */ public void multiLevelBulletedListInCell(HSSFWorkbook workbook, - ArrayList<MultiLevelListItem> multiLevelListItems, + List<MultiLevelListItem> multiLevelListItems, HSSFCell cell) { StringBuilder buffer = new StringBuilder(); // Note that again, an HSSFCellStye object is required and that @@ -448,8 +451,8 @@ public class InCellLists { buffer.append("\n"); // and then an ArrayList whose elements encapsulate the text // for the lower level list items. - ArrayList<String> lowerLevelItems = multiLevelListItem.getLowerLevelItems(); - if(!(lowerLevelItems == null) && !(lowerLevelItems.isEmpty())) { + List<String> lowerLevelItems = multiLevelListItem.getLowerLevelItems(); + if(lowerLevelItems != null && !lowerLevelItems.isEmpty()) { for(String item : lowerLevelItems) { buffer.append(InCellLists.TAB); buffer.append(InCellLists.BULLET_CHARACTER); @@ -498,7 +501,7 @@ public class InCellLists { public final class MultiLevelListItem { private String itemText; - private ArrayList<String> lowerLevelItems; + private List<String> lowerLevelItems; /** * Create a new instance of the MultiLevelListItem class using the @@ -510,7 +513,7 @@ public class InCellLists { * text for the associated lower level list * items. */ - public MultiLevelListItem(String itemText, ArrayList<String> lowerLevelItems) { + public MultiLevelListItem(String itemText, List<String> lowerLevelItems) { this.itemText = itemText; this.lowerLevelItems = lowerLevelItems; } @@ -531,8 +534,8 @@ public class InCellLists { * @return An ArrayList whose elements each encapsulate the text for a * single associated lower level list item. */ - public ArrayList<String> getLowerLevelItems() { - return(this.lowerLevelItems); + public List<String> getLowerLevelItems() { + return lowerLevelItems; } } } |