瀏覽代碼

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
tags/before_ooxml_3rd_edition
Andreas Beeker 4 年之前
父節點
當前提交
661c0b66bc
共有 43 個檔案被更改,包括 335 行新增1395 行删除
  1. 8
    5
      src/examples/src/org/apache/poi/crypt/examples/OOXMLPasswordsTry.java
  2. 52
    203
      src/examples/src/org/apache/poi/hpsf/examples/CopyCompare.java
  3. 2
    1
      src/examples/src/org/apache/poi/hpsf/examples/ReadCustomPropertySets.java
  4. 3
    2
      src/examples/src/org/apache/poi/hpsf/examples/WriteAuthorAndTitle.java
  5. 2
    1
      src/examples/src/org/apache/poi/hslf/examples/ApacheconEU08.java
  6. 26
    27
      src/examples/src/org/apache/poi/hslf/examples/DataExtraction.java
  7. 1
    1
      src/examples/src/org/apache/poi/hslf/examples/Graphics2DDemo.java
  8. 11
    12
      src/examples/src/org/apache/poi/hsmf/examples/Msg2txt.java
  9. 4
    4
      src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java
  10. 2
    869
      src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java
  11. 0
    1
      src/examples/src/org/apache/poi/hssf/usermodel/examples/BigExample.java
  12. 25
    17
      src/examples/src/org/apache/poi/hssf/usermodel/examples/EmbeddedObjects.java
  13. 12
    6
      src/examples/src/org/apache/poi/hssf/usermodel/examples/EventExample.java
  14. 3
    0
      src/examples/src/org/apache/poi/hssf/usermodel/examples/HSSFReadWrite.java
  15. 9
    9
      src/examples/src/org/apache/poi/hssf/usermodel/examples/Hyperlinks.java
  16. 29
    26
      src/examples/src/org/apache/poi/hssf/usermodel/examples/InCellLists.java
  17. 1
    1
      src/java/org/apache/poi/hpsf/ClipboardData.java
  18. 1
    1
      src/java/org/apache/poi/hpsf/Property.java
  19. 1
    1
      src/java/org/apache/poi/hssf/record/CFRule12Record.java
  20. 7
    7
      src/java/org/apache/poi/poifs/filesystem/DocumentOutputStream.java
  21. 1
    1
      src/java/org/apache/poi/sl/draw/PathGradientPaint.java
  22. 1
    1
      src/java/org/apache/poi/ss/formula/atp/YearFracCalculator.java
  23. 4
    6
      src/java/org/apache/poi/ss/formula/functions/BaseNumberUtils.java
  24. 3
    3
      src/java/org/apache/poi/ss/formula/functions/Column.java
  25. 1
    1
      src/java/org/apache/poi/ss/formula/functions/Match.java
  26. 1
    1
      src/java/org/apache/poi/ss/formula/functions/Mirr.java
  27. 3
    5
      src/java/org/apache/poi/ss/formula/functions/RowFunc.java
  28. 20
    14
      src/java/org/apache/poi/ss/formula/functions/TextFunction.java
  29. 9
    9
      src/java/org/apache/poi/ss/formula/functions/Trend.java
  30. 4
    2
      src/java/org/apache/poi/ss/formula/functions/WeekdayFunc.java
  31. 1
    1
      src/java/org/apache/poi/ss/usermodel/DateUtil.java
  32. 1
    1
      src/java/org/apache/poi/util/LZWDecompresser.java
  33. 10
    10
      src/java/org/apache/poi/util/RLEDecompressingInputStream.java
  34. 2
    3
      src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPage.java
  35. 3
    3
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java
  36. 3
    3
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java
  37. 47
    29
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java
  38. 1
    1
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java
  39. 1
    1
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java
  40. 11
    53
      src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
  41. 1
    1
      src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
  42. 5
    6
      src/testcases/org/apache/poi/poifs/crypt/TestBiff8DecryptingStream.java
  43. 3
    46
      src/testcases/org/apache/poi/poifs/storage/RawDataUtil.java

+ 8
- 5
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"));
}
}
}


+ 52
- 203
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);
}
}

}

+ 2
- 1
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: */

+ 3
- 2
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. */

+ 2
- 1
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);

+ 26
- 27
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());

+ 1
- 1
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,

+ 11
- 12
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) {

+ 4
- 4
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) + "]:"
);

+ 2
- 869
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 {
}

+ 0
- 1
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

+ 25
- 17
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();

+ 12
- 6
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;


+ 3
- 0
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.
*/

+ 9
- 9
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);

+ 29
- 26
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;
}
}
}

+ 1
- 1
src/java/org/apache/poi/hpsf/ClipboardData.java 查看文件

@@ -36,7 +36,7 @@ public class ClipboardData {

public void read( LittleEndianByteArrayInputStream lei ) {
int offset = lei.getReadIndex();
int size = lei.readInt();
long size = lei.readInt();

if ( size < 4 ) {
String msg =

+ 1
- 1
src/java/org/apache/poi/hpsf/Property.java 查看文件

@@ -417,7 +417,7 @@ public class Property {

// skip length field
if(bos.size() > 2*LittleEndianConsts.INT_SIZE) {
final String hex = HexDump.dump(bos.toByteArray(), -2*LittleEndianConsts.INT_SIZE, 2*LittleEndianConsts.INT_SIZE);
final String hex = HexDump.dump(bos.toByteArray(), -2L*LittleEndianConsts.INT_SIZE, 2*LittleEndianConsts.INT_SIZE);
b.append(hex);
}
} else if (value instanceof byte[]) {

+ 1
- 1
src/java/org/apache/poi/hssf/record/CFRule12Record.java 查看文件

@@ -265,7 +265,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
// 2 bytes reserved
in.readUShort();
} else {
int len = readFormatOptions(in);
long len = readFormatOptions(in);
if (len < ext_formatting_length) {
ext_formatting_data = IOUtils.safelyAllocate(ext_formatting_length-len, MAX_RECORD_LENGTH);
in.readFully(ext_formatting_data);

+ 7
- 7
src/java/org/apache/poi/poifs/filesystem/DocumentOutputStream.java 查看文件

@@ -40,11 +40,11 @@ public final class DocumentOutputStream extends OutputStream {
private POIFSDocument _document;
/** and its Property */
private DocumentProperty _property;
/** our buffer, when null we're into normal blocks */
private ByteArrayOutputStream _buffer =
private ByteArrayOutputStream _buffer =
new ByteArrayOutputStream(POIFSConstants.BIG_BLOCK_MINIMUM_DOCUMENT_SIZE);
/** our main block stream, when we're into normal blocks */
private POIFSStream _stream;
private OutputStream _stream_output;
@@ -56,7 +56,7 @@ public final class DocumentOutputStream extends OutputStream {
/**
* Create an OutputStream from the specified DocumentEntry.
* The specified entry will be emptied.
*
*
* @param document the DocumentEntry to be written
*/
public DocumentOutputStream(DocumentEntry document) throws IOException {
@@ -65,7 +65,7 @@ public final class DocumentOutputStream extends OutputStream {

/**
* Create an OutputStream to create the specified new Entry
*
*
* @param parent Where to create the Entry
* @param name Name of the new entry
*/
@@ -159,7 +159,7 @@ public final class DocumentOutputStream extends OutputStream {
_property.updateSize(_document_size);
_property.setStartBlock(_stream.getStartBlock());
}
// No more!
_closed = true;
}
@@ -168,6 +168,6 @@ public final class DocumentOutputStream extends OutputStream {
* @return the amount of written bytes
*/
public long size() {
return _document_size + (_buffer == null ? 0 : _buffer.size());
return _document_size + (_buffer == null ? 0L : _buffer.size());
}
}

+ 1
- 1
src/java/org/apache/poi/sl/draw/PathGradientPaint.java 查看文件

@@ -199,7 +199,7 @@ public class PathGradientPaint implements Paint {
// it doesn't work to use just a color with transparency ...
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, rgb[3]/255.0f));
}
graphics.setStroke(new BasicStroke(i+1, capStyle, joinStyle));
graphics.setStroke(new BasicStroke(i+1F, capStyle, joinStyle));
graphics.setColor(c);
if (i == gradientSteps-1) {
graphics.fill(shape);

+ 1
- 1
src/java/org/apache/poi/ss/formula/atp/YearFracCalculator.java 查看文件

@@ -270,7 +270,7 @@ final class YearFracCalculator {
for (int i=startYear; i<=endYear; i++) {
dayCount += isLeapYear(i) ? DAYS_PER_LEAP_YEAR : DAYS_PER_NORMAL_YEAR;
}
double numberOfYears = endYear-startYear+1;
double numberOfYears = endYear-startYear+1.;
return dayCount / numberOfYears;
}


+ 4
- 6
src/java/org/apache/poi/ss/formula/functions/BaseNumberUtils.java 查看文件

@@ -17,9 +17,7 @@
package org.apache.poi.ss.formula.functions;

/**
* <p>Some utils for converting from and to any base<p>
*
* @author cedric dot walter @ gmail dot com
* Some utils for converting from and to any base
*/
public class BaseNumberUtils {

@@ -43,11 +41,11 @@ public class BaseNumberUtils {
long digit;

if ('0' <= character && character <= '9') {
digit = character - '0';
digit = (long)character - '0';
} else if ('A' <= character && character <= 'Z') {
digit = 10 + (character - 'A');
digit = 10L + (character - 'A');
} else if ('a' <= character && character <= 'z') {
digit = 10 + (character - 'a');
digit = 10L + (character - 'a');
} else {
digit = base;
}

+ 3
- 3
src/java/org/apache/poi/ss/formula/functions/Column.java 查看文件

@@ -26,7 +26,7 @@ import org.apache.poi.ss.formula.eval.ValueEval;
public final class Column implements Function0Arg, Function1Arg {

public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
return new NumberEval(srcColumnIndex+1);
return new NumberEval(srcColumnIndex+1.);
}
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
int rnum;
@@ -40,14 +40,14 @@ public final class Column implements Function0Arg, Function1Arg {
return ErrorEval.VALUE_INVALID;
}

return new NumberEval(rnum + 1);
return new NumberEval(rnum + 1.);
}
public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
switch (args.length) {
case 1:
return evaluate(srcRowIndex, srcColumnIndex, args[0]);
case 0:
return new NumberEval(srcColumnIndex+1);
return new NumberEval(srcColumnIndex+1.);
}
return ErrorEval.VALUE_INVALID;
}

+ 1
- 1
src/java/org/apache/poi/ss/formula/functions/Match.java 查看文件

@@ -95,7 +95,7 @@ public final class Match extends Var2or3ArgFunction {
ValueEval lookupValue = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);
ValueVector lookupRange = evaluateLookupRange(arg1);
int index = findIndexOfValue(lookupValue, lookupRange, matchExact, findLargestLessThanOrEqual);
return new NumberEval(index + 1); // +1 to convert to 1-based
return new NumberEval(index + 1.); // +1 to convert to 1-based
} catch (EvaluationException e) {
return e.getErrorEval();
}

+ 1
- 1
src/java/org/apache/poi/ss/formula/functions/Mirr.java 查看文件

@@ -85,7 +85,7 @@ public class Mirr extends MultiOperandNumericFunction {

private static double mirr(double[] in, double financeRate, double reinvestRate) {
double value = 0;
int numOfYears = in.length - 1;
double numOfYears = in.length - 1;
double pv = 0;
double fv = 0;


+ 3
- 5
src/java/org/apache/poi/ss/formula/functions/RowFunc.java 查看文件

@@ -25,13 +25,11 @@ import org.apache.poi.ss.formula.eval.ValueEval;

/**
* Implementation for the Excel function ROW
*
* @author Josh Micich
*/
public final class RowFunc implements Function0Arg, Function1Arg {

public ValueEval evaluate(int srcRowIndex, int srcColumnIndex) {
return new NumberEval(srcRowIndex+1);
return new NumberEval(srcRowIndex+1.);
}
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
int rnum;
@@ -45,14 +43,14 @@ public final class RowFunc implements Function0Arg, Function1Arg {
return ErrorEval.VALUE_INVALID;
}

return new NumberEval(rnum + 1);
return new NumberEval(rnum + 1.);
}
public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
switch (args.length) {
case 1:
return evaluate(srcRowIndex, srcColumnIndex, args[0]);
case 0:
return new NumberEval(srcRowIndex+1);
return new NumberEval(srcRowIndex+1.);
}
return ErrorEval.VALUE_INVALID;
}

+ 20
- 14
src/java/org/apache/poi/ss/formula/functions/TextFunction.java 查看文件

@@ -17,11 +17,17 @@

package org.apache.poi.ss.formula.functions;

import org.apache.poi.ss.formula.eval.*;
import org.apache.poi.ss.usermodel.DataFormatter;

import java.util.Locale;

import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.EvaluationException;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.OperandResolver;
import org.apache.poi.ss.formula.eval.StringEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.usermodel.DataFormatter;

/**
* @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
* @author Josh Micich
@@ -38,7 +44,7 @@ public abstract class TextFunction implements Function {
ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
return OperandResolver.coerceValueToInt(ve);
}
protected static double evaluateDoubleArg(ValueEval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
return OperandResolver.coerceValueToDouble(ve);
@@ -112,7 +118,7 @@ public abstract class TextFunction implements Function {
* Implementation of the PROPER function:
* Normalizes all words (separated by non-word characters) by
* making the first letter upper and the rest lower case.
*
*
* This is nearly equivalent to toTitleCase if the Java language had it
*/
public static final Function PROPER = new SingleArgTextFunc() {
@@ -147,7 +153,7 @@ public abstract class TextFunction implements Function {
return new StringEval(arg.trim());
}
};
/**
* An implementation of the CLEAN function:
* In Excel, the Clean function removes all non-printable characters from a string.
@@ -244,11 +250,11 @@ public abstract class TextFunction implements Function {
} catch (EvaluationException e) {
return e.getErrorEval();
}
if(index < 0) {
return ErrorEval.VALUE_INVALID;
}
String result;
if (_isLeft) {
result = arg.substring(0, Math.min(arg.length(), index));
@@ -295,11 +301,11 @@ public abstract class TextFunction implements Function {

/**
* An implementation of the TEXT function<br>
* TEXT returns a number value formatted with the given number formatting string.
* TEXT returns a number value formatted with the given number formatting string.
* This function is not a complete implementation of the Excel function, but
* handles most of the common cases. All work is passed down to
* handles most of the common cases. All work is passed down to
* {@link DataFormatter} to be done, as this works much the same as the
* display focused work that that does.
* display focused work that that does.
*
* <b>Syntax<b>:<br> <b>TEXT</b>(<b>value</b>, <b>format_text</b>)<br>
*/
@@ -314,7 +320,7 @@ public abstract class TextFunction implements Function {
} catch (EvaluationException e) {
return e.getErrorEval();
}
try {
// Ask DataFormatter to handle the String for us
String formattedStr = formatter.formatRawCellContents(s0, -1, s1);
@@ -324,7 +330,7 @@ public abstract class TextFunction implements Function {
}
}
};
private static final class SearchFind extends Var2or3ArgFunction {

private final boolean _isCaseSensitive;
@@ -367,7 +373,7 @@ public abstract class TextFunction implements Function {
if (result == -1) {
return ErrorEval.VALUE_INVALID;
}
return new NumberEval(result + 1);
return new NumberEval(result + 1.);
}
}
/**

+ 9
- 9
src/java/org/apache/poi/ss/formula/functions/Trend.java 查看文件

@@ -25,6 +25,10 @@

package org.apache.poi.ss.formula.functions;

import java.util.Arrays;

import org.apache.commons.math3.linear.SingularMatrixException;
import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression;
import org.apache.poi.ss.formula.CacheAreaEval;
import org.apache.poi.ss.formula.eval.AreaEval;
import org.apache.poi.ss.formula.eval.BoolEval;
@@ -36,15 +40,11 @@ import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.NumericValueEval;
import org.apache.poi.ss.formula.eval.RefEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.commons.math3.linear.SingularMatrixException;
import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression;

import java.util.Arrays;


/**
* Implementation for the Excel function TREND<p>
*
*
* Syntax:<br>
* TREND(known_y's, known_x's, new_x's, constant)
* <table border="0" cellpadding="1" cellspacing="0" summary="Parameter descriptions">
@@ -131,14 +131,14 @@ public final class Trend implements Function {
} else {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
return ar;
}

private static double[][] getDefaultArrayOneD(int w) {
double[][] array = new double[w][1];
for (int i = 0; i < w; i++) {
array[i][0] = i + 1;
array[i][0] = i + 1.;
}
return array;
}
@@ -319,11 +319,11 @@ public final class Trend implements Function {
} else if (newXOrig.length == 1 && newXOrig[0].length > 1 && xOrig.length > 1 && xOrig[0].length == 1) {
newX = switchRowsColumns(newXOrig);
}
if (newX[0].length != x[0].length) {
throw new EvaluationException(ErrorEval.REF_INVALID);
}
if (x[0].length >= x.length) {
/* See comment at top of file */
throw new NotImplementedException("Sample size too small");

+ 4
- 2
src/java/org/apache/poi/ss/formula/functions/WeekdayFunc.java 查看文件

@@ -114,9 +114,11 @@ public final class WeekdayFunc implements Function {
} else if (returnOption == 3) {
result = (weekday + 6 - 1) % 7;
} else if (returnOption >= 11 && returnOption <= 17) {
result = (weekday + 6 - (returnOption - 10)) % 7 + 1; // rotate in the value range 1 to 7
// rotate in the value range 1 to 7
result = (weekday + 6 - (returnOption - 10)) % 7 + 1.;
} else {
return ErrorEval.NUM_ERROR; // EXCEL uses this and no VALUE_ERROR
// EXCEL uses this and no VALUE_ERROR
return ErrorEval.NUM_ERROR;
}

return new NumberEval(result);

+ 1
- 1
src/java/org/apache/poi/ss/usermodel/DateUtil.java 查看文件

@@ -428,7 +428,7 @@ public class DateUtil {
}

LocalDateTime ldt = LocalDateTime.of(startYear, 1, 1, 0, 0);
ldt = ldt.plusDays(wholeDays+dayAdjust-1);
ldt = ldt.plusDays(wholeDays+dayAdjust-1L);

long nanosTime =
bd.subtract(BigDecimal.valueOf(wholeDays))

+ 1
- 1
src/java/org/apache/poi/util/LZWDecompresser.java 查看文件

@@ -128,7 +128,7 @@ public abstract class LZWDecompresser {
// These are bytes as looked up in the dictionary
// It needs to be signed, as it'll get passed on to
// the output stream
final byte[] dataB = IOUtils.safelyAllocate(16 + codeLengthIncrease, MAX_RECORD_LENGTH);
final byte[] dataB = IOUtils.safelyAllocate(16L + codeLengthIncrease, MAX_RECORD_LENGTH);
// This is an unsigned byte read from the stream
// It needs to be unsigned, so that bit stuff works
int dataI;

+ 10
- 10
src/java/org/apache/poi/util/RLEDecompressingInputStream.java 查看文件

@@ -17,14 +17,14 @@

package org.apache.poi.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
* Wrapper of InputStream which provides Run Length Encoding (RLE)
* Wrapper of InputStream which provides Run Length Encoding (RLE)
* decompression on the fly. Uses MS-OVBA decompression algorithm. See
* http://download.microsoft.com/download/2/4/8/24862317-78F0-4C4B-B355-C7B2C1D997DB/[MS-OVBA].pdf
*/
@@ -66,7 +66,7 @@ public class RLEDecompressingInputStream extends InputStream {

/**
* Creates a new wrapper RLE Decompression InputStream.
*
*
* @param in The stream to wrap with the RLE Decompression
* @throws IOException
*/
@@ -131,7 +131,7 @@ public class RLEDecompressingInputStream extends InputStream {
return -1;
}
}
int c = (int) Math.min(n, len - pos);
int c = (int) Math.min(n, len - (long)pos);
pos += c;
length -= c;
}
@@ -150,7 +150,7 @@ public class RLEDecompressingInputStream extends InputStream {

/**
* Reads a single chunk from the underlying inputstream.
*
*
* @return number of bytes that were read, or -1 if the end of the stream was reached.
* @throws IOException
*/
@@ -215,7 +215,7 @@ public class RLEDecompressingInputStream extends InputStream {

/**
* Helper method to determine how many bits in the CopyToken are used for the CopyLength.
*
*
* @param offset
* @return returns the number of bits in the copy token (a value between 4 and 12)
*/
@@ -230,7 +230,7 @@ public class RLEDecompressingInputStream extends InputStream {

/**
* Convenience method for read a 2-bytes short in little endian encoding.
*
*
* @return short value from the stream, -1 if end of stream is reached
* @throws IOException
*/
@@ -240,7 +240,7 @@ public class RLEDecompressingInputStream extends InputStream {

/**
* Convenience method for read a 4-bytes int in little endian encoding.
*
*
* @return integer value from the stream, -1 if end of stream is reached
* @throws IOException
*/
@@ -279,7 +279,7 @@ public class RLEDecompressingInputStream extends InputStream {
public static byte[] decompress(byte[] compressed) throws IOException {
return decompress(compressed, 0, compressed.length);
}
public static byte[] decompress(byte[] compressed, int offset, int length) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream instream = new ByteArrayInputStream(compressed, offset, length);

+ 2
- 3
src/ooxml/java/org/apache/poi/xdgf/usermodel/XDGFPage.java 查看文件

@@ -20,12 +20,11 @@ package org.apache.poi.xdgf.usermodel;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import com.microsoft.schemas.office.visio.x2012.main.PageType;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.util.Internal;
import org.apache.poi.xdgf.geom.Dimension2dDouble;

import com.microsoft.schemas.office.visio.x2012.main.PageType;

/**
* Provides the API to work with an underlying page
*/
@@ -69,7 +68,7 @@ public class XDGFPage {
}

public long getPageNumber() {
return _pages.getPageList().indexOf(this) + 1;
return _pages.getPageList().indexOf(this) + 1L;
}

/**

+ 3
- 3
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChart.java 查看文件

@@ -195,7 +195,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
@Deprecated
@Removal(version = "4.2")
public XSSFValueAxis createValueAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) {
long id = axis.size() + 1;
long id = axis.size() + 1L;
XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos);
if (axis.size() == 1) {
ChartAxis ax = axis.get(0);
@@ -210,7 +210,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
@Deprecated
@Removal(version = "4.2")
public XSSFCategoryAxis createCategoryAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) {
long id = axis.size() + 1;
long id = axis.size() + 1L;
XSSFCategoryAxis categoryAxis = new XSSFCategoryAxis(this, id, pos);
if (axis.size() == 1) {
ChartAxis ax = axis.get(0);
@@ -225,7 +225,7 @@ public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactor
@Deprecated
@Removal(version = "4.2")
public XSSFDateAxis createDateAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) {
long id = axis.size() + 1;
long id = axis.size() + 1L;
XSSFDateAxis dateAxis = new XSSFDateAxis(this, id, pos);
if (axis.size() == 1) {
ChartAxis ax = axis.get(0);

+ 3
- 3
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java 查看文件

@@ -17,10 +17,10 @@

package org.apache.poi.xssf.usermodel;

import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.apache.poi.util.Internal;

/**
* @author Yegor Kozlov
@@ -71,7 +71,7 @@ public final class XSSFChildAnchor extends XSSFAnchor {
}

public void setDy2(int dy2) {
t2d.getExt().setCy(dy2 - getDy1());
t2d.getExt().setCy(dy2 - (long)getDy1());
}

public int getDx2() {
@@ -79,6 +79,6 @@ public final class XSSFChildAnchor extends XSSFAnchor {
}

public void setDx2(int dx2) {
t2d.getExt().setCx(dx2 - getDx1());
t2d.getExt().setCx(dx2 - (long)getDx1());
}
}

+ 47
- 29
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConditionalFormattingRule.java 查看文件

@@ -22,11 +22,29 @@ package org.apache.poi.xssf.usermodel;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.ComparisonOperator;
import org.apache.poi.ss.usermodel.ConditionFilterData;
import org.apache.poi.ss.usermodel.ConditionFilterType;
import org.apache.poi.ss.usermodel.ConditionType;
import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
import org.apache.poi.ss.usermodel.ConditionalFormattingThreshold.RangeType;
import org.apache.poi.ss.usermodel.ExcelNumberFormat;
import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;
import org.apache.poi.xssf.model.StylesTable;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfvo;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColorScale;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataBar;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDxf;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFill;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIconSet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTNumFmt;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfType;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCfvoType;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STConditionalFormattingOperator;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STIconSetType;

/**
* XSSF support for Conditional Formatting rules
@@ -34,7 +52,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
public class XSSFConditionalFormattingRule implements ConditionalFormattingRule {
private final CTCfRule _cfRule;
private XSSFSheet _sh;
private static Map<STCfType.Enum, ConditionType> typeLookup = new HashMap<>();
private static Map<STCfType.Enum, ConditionFilterType> filterTypeLookup = new HashMap<>();
static {
@@ -43,7 +61,7 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
typeLookup.put(STCfType.COLOR_SCALE, ConditionType.COLOR_SCALE);
typeLookup.put(STCfType.DATA_BAR, ConditionType.DATA_BAR);
typeLookup.put(STCfType.ICON_SET, ConditionType.ICON_SET);
// These are all subtypes of Filter, we think...
typeLookup.put(STCfType.TOP_10, ConditionType.FILTER);
typeLookup.put(STCfType.UNIQUE_VALUES, ConditionType.FILTER);
@@ -58,7 +76,7 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
typeLookup.put(STCfType.NOT_CONTAINS_ERRORS, ConditionType.FILTER);
typeLookup.put(STCfType.TIME_PERIOD, ConditionType.FILTER);
typeLookup.put(STCfType.ABOVE_AVERAGE, ConditionType.FILTER);
filterTypeLookup.put(STCfType.TOP_10, ConditionFilterType.TOP_10);
filterTypeLookup.put(STCfType.UNIQUE_VALUES, ConditionFilterType.UNIQUE_VALUES);
filterTypeLookup.put(STCfType.DUPLICATE_VALUES, ConditionFilterType.DUPLICATE_VALUES);
@@ -74,7 +92,7 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
filterTypeLookup.put(STCfType.ABOVE_AVERAGE, ConditionFilterType.ABOVE_AVERAGE);

}
/**
* NOTE: does not set priority, so this assumes the rule will not be added to the sheet yet
* @param sh
@@ -103,7 +121,7 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
if(create && dxf == null) {
dxf = CTDxf.Factory.newInstance();
int dxfId = styles.putDxf(dxf);
_cfRule.setDxfId(dxfId - 1);
_cfRule.setDxfId(dxfId - 1L);
}
return dxf;
}
@@ -113,11 +131,11 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
// priorities start at 1, if it is less, it is undefined, use definition order in caller
return priority >=1 ? priority : 0;
}
public boolean getStopIfTrue() {
return _cfRule.getStopIfTrue();
}
/**
* Create a new border formatting structure if it does not exist,
* otherwise just return existing object.
@@ -201,7 +219,7 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule

return new XSSFPatternFormatting(dxf.getFill(), _sh.getWorkbook().getStylesSource().getIndexedColors());
}
/**
*
* @param color
@@ -211,7 +229,7 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
// Is it already there?
if (_cfRule.isSetDataBar() && _cfRule.getType() == STCfType.DATA_BAR)
return getDataBarFormatting();
// Mark it as being a Data Bar
_cfRule.setType(STCfType.DATA_BAR);

@@ -224,13 +242,13 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
}
// Set the color
bar.setColor(color.getCTColor());
// Add the default thresholds
CTCfvo min = bar.addNewCfvo();
min.setType(STCfvoType.Enum.forString(RangeType.MIN.name));
CTCfvo max = bar.addNewCfvo();
max.setType(STCfvoType.Enum.forString(RangeType.MAX.name));
// Wrap and return
return new XSSFDataBarFormatting(bar, _sh.getWorkbook().getStylesSource().getIndexedColors());
}
@@ -242,12 +260,12 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
return null;
}
}
public XSSFIconMultiStateFormatting createMultiStateFormatting(IconSet iconSet) {
// Is it already there?
if (_cfRule.isSetIconSet() && _cfRule.getType() == STCfType.ICON_SET)
return getMultiStateFormatting();
// Mark it as being an Icon Set
_cfRule.setType(STCfType.ICON_SET);

@@ -263,7 +281,7 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
STIconSetType.Enum xIconSet = STIconSetType.Enum.forString(iconSet.name);
icons.setIconSet(xIconSet);
}
// Add a default set of thresholds
int jump = 100 / iconSet.num;
STCfvoType.Enum type = STCfvoType.Enum.forString(RangeType.PERCENT.name);
@@ -272,7 +290,7 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
cfvo.setType(type);
cfvo.setVal(Integer.toString(i*jump));
}
// Wrap and return
return new XSSFIconMultiStateFormatting(icons);
}
@@ -284,12 +302,12 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
return null;
}
}
public XSSFColorScaleFormatting createColorScaleFormatting() {
// Is it already there?
if (_cfRule.isSetColorScale() && _cfRule.getType() == STCfType.COLOR_SCALE)
return getColorScaleFormatting();
// Mark it as being a Color Scale
_cfRule.setType(STCfType.COLOR_SCALE);

@@ -300,7 +318,7 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
} else {
scale = _cfRule.addNewColorScale();
}
// Add a default set of thresholds and colors
if (scale.sizeOfCfvoArray() == 0) {
CTCfvo cfvo;
@@ -311,12 +329,12 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
cfvo.setVal("50");
cfvo = scale.addNewCfvo();
cfvo.setType(STCfvoType.Enum.forString(RangeType.MAX.name));
for (int i=0; i<3; i++) {
scale.addNewColor();
}
}
// Wrap and return
return new XSSFColorScaleFormatting(scale, _sh.getWorkbook().getStylesSource().getIndexedColors());
}
@@ -336,11 +354,11 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
public ExcelNumberFormat getNumberFormat() {
CTDxf dxf = getDxf(false);
if(dxf == null || !dxf.isSetNumFmt()) return null;
CTNumFmt numFmt = dxf.getNumFmt();
return new ExcelNumberFormat((int) numFmt.getNumFmtId(), numFmt.getFormatCode());
}
/**
* Type of conditional formatting rule.
*/
@@ -356,11 +374,11 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
public ConditionFilterType getConditionFilterType() {
return filterTypeLookup.get(_cfRule.getType());
}
public ConditionFilterData getFilterConfiguration() {
return new XSSFConditionFilterData(_cfRule);
}
/**
* The comparison function used when the type of conditional formatting is set to
* {@link ConditionType#CELL_VALUE_IS}
@@ -374,7 +392,7 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
public byte getComparisonOperation(){
STConditionalFormattingOperator.Enum op = _cfRule.getOperator();
if(op == null) return ComparisonOperator.NO_COMPARISON;
switch(op.intValue()){
case STConditionalFormattingOperator.INT_LESS_THAN: return ComparisonOperator.LT;
case STConditionalFormattingOperator.INT_LESS_THAN_OR_EQUAL: return ComparisonOperator.LE;
@@ -416,11 +434,11 @@ public class XSSFConditionalFormattingRule implements ConditionalFormattingRule
public String getFormula2(){
return _cfRule.sizeOfFormulaArray() == 2 ? _cfRule.getFormulaArray(1) : null;
}
public String getText() {
return _cfRule.getText();
}
/**
* Conditional format rules don't define stripes, so always 0
* @see org.apache.poi.ss.usermodel.DifferentialStyleProvider#getStripeSize()

+ 1
- 1
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java 查看文件

@@ -583,7 +583,7 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing<XSS
}

private long newShapeId() {
return 1 + drawing.sizeOfAbsoluteAnchorArray() + drawing.sizeOfOneCellAnchorArray() + drawing
return 1L + drawing.sizeOfAbsoluteAnchorArray() + drawing.sizeOfOneCellAnchorArray() + drawing
.sizeOfTwoCellAnchorArray();
}


+ 1
- 1
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java 查看文件

@@ -423,7 +423,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
throw new IllegalArgumentException("Invalid row number (" + rowIndex
+ ") outside allowable range (0.." + maxrow + ")");
}
_row.setR(rowIndex + 1);
_row.setR(rowIndex + 1L);
}

/**

+ 11
- 53
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java 查看文件

@@ -92,50 +92,7 @@ import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAutoFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidations;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIgnoredError;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIgnoredErrors;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTLegacyDrawing;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOleObject;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOleObjects;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOutlinePr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetUpPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPane;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPrintOptions;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSelection;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetCalcPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTablePart;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableParts;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPaneState;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;

/**
* High level representation of a SpreadsheetML worksheet.
@@ -1916,9 +1873,11 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {

private void setBreak(int id, CTPageBreak ctPgBreak, int lastIndex) {
CTBreak brk = ctPgBreak.addNewBrk();
brk.setId(id + 1); // this is id of the element which is 1-based: <row r="1" ... >
// this is id of the element which is 1-based: <row r="1" ... >
brk.setId(id + 1L);
brk.setMan(true);
brk.setMax(lastIndex); //end column of the break
// end column of the break
brk.setMax(lastIndex);

int nPageBreaks = ctPgBreak.sizeOfBrkArray();
ctPgBreak.setCount(nPageBreaks);
@@ -2256,13 +2215,12 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
}

if (ciMin == targetColumnIx || ciMax == targetColumnIx) {
// The target column is at either end of the multi-column ColumnInfo
// ci
// The target column is at either end of the multi-column ColumnInfo ci
// we'll just divide the info and create a new one
if (ciMin == targetColumnIx) {
ci.setMin(targetColumnIx + 1);
ci.setMin(targetColumnIx + 1L);
} else {
ci.setMax(targetColumnIx - 1);
ci.setMax(targetColumnIx - 1L);
}
CTCol nci = columnHelper.cloneCol(cols, ci);
nci.setMin(targetColumnIx);
@@ -2275,14 +2233,14 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
CTCol ciEnd = columnHelper.cloneCol(cols, ci);
int lastcolumn = Math.toIntExact(ciMax);

ci.setMax(targetColumnIx - 1);
ci.setMax(targetColumnIx - 1L);

ciMid.setMin(targetColumnIx);
ciMid.setMax(targetColumnIx);
unsetCollapsed(collapsed, ciMid);
this.columnHelper.addCleanColIntoCols(cols, ciMid);

ciEnd.setMin(targetColumnIx + 1);
ciEnd.setMin(targetColumnIx + 1L);
ciEnd.setMax(lastcolumn);
this.columnHelper.addCleanColIntoCols(cols, ciEnd);
}
@@ -4069,7 +4027,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
int currentCount = dataValidations.sizeOfDataValidationArray();
CTDataValidation newval = dataValidations.addNewDataValidation();
newval.set(xssfDataValidation.getCtDdataValidation());
dataValidations.setCount(currentCount + 1);
dataValidations.setCount(currentCount + 1L);

}


+ 1
- 1
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java 查看文件

@@ -152,7 +152,7 @@ public class XWPFNumbering extends POIXMLDocumentPart {
CTNum ctNum = this.ctNumbering.addNewNum();
ctNum.addNewAbstractNumId();
ctNum.getAbstractNumId().setVal(abstractNumID);
ctNum.setNumId(BigInteger.valueOf(nums.size() + 1));
ctNum.setNumId(BigInteger.valueOf(nums.size() + 1L));
XWPFNum num = new XWPFNum(ctNum, this);
nums.add(num);
return ctNum.getNumId();

+ 5
- 6
src/testcases/org/apache/poi/poifs/crypt/TestBiff8DecryptingStream.java 查看文件

@@ -26,7 +26,6 @@ import java.io.InputStream;
import javax.crypto.spec.SecretKeySpec;

import org.apache.poi.hssf.record.crypto.Biff8DecryptingStream;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.HexRead;
import org.junit.Test;

@@ -87,15 +86,15 @@ public final class TestBiff8DecryptingStream {
}

public void confirmByte(int expVal) {
assertEquals(HexDump.byteToHex(expVal), HexDump.byteToHex(_bds.readUByte()));
assertEquals(expVal, _bds.readUByte());
}

public void confirmShort(int expVal) {
assertEquals(HexDump.shortToHex(expVal), HexDump.shortToHex(_bds.readShort()));
assertEquals((short)expVal, _bds.readShort());
}

public void confirmUShort(int expVal) {
assertEquals(HexDump.shortToHex(expVal), HexDump.shortToHex(_bds.readUShort()));
assertEquals(expVal, _bds.readUShort());
}

public short readShort() {
@@ -107,11 +106,11 @@ public final class TestBiff8DecryptingStream {
}

public void confirmInt(int expVal) {
assertEquals(HexDump.intToHex(expVal), HexDump.intToHex(_bds.readInt()));
assertEquals(expVal, _bds.readInt());
}

public void confirmLong(long expVal) {
assertEquals(HexDump.longToHex(expVal), HexDump.longToHex(_bds.readLong()));
assertEquals(expVal, _bds.readLong());
}

public void confirmData(String expHexData) {

+ 3
- 46
src/testcases/org/apache/poi/poifs/storage/RawDataUtil.java 查看文件

@@ -19,11 +19,9 @@ package org.apache.poi.poifs.storage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Base64;
import java.util.zip.GZIPInputStream;

import org.apache.poi.util.HexDump;
import org.apache.poi.util.HexRead;
import org.apache.poi.util.IOUtils;

@@ -31,11 +29,11 @@ import org.apache.poi.util.IOUtils;
* Test utility class.<br>
*
* Creates raw <code>byte[]</code> data from hex-dump String arrays.
*
* @author Josh Micich
*/
public final class RawDataUtil {

private RawDataUtil() {}

public static byte[] decode(String[] hexDataLines) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(hexDataLines.length * 32 + 32);

@@ -46,47 +44,6 @@ public final class RawDataUtil {
return baos.toByteArray();
}

/**
* Development time utility method.<br>
* Transforms a byte array into hex-dump String lines in java source code format.
*/
public static void dumpData(byte[] data) {
int i=0;
System.out.println("String[] hexDataLines = {");
System.out.print("\t\"");
while(true) {
System.out.print(HexDump.byteToHex(data[i]).substring(2));
i++;
if (i>=data.length) {
break;
}
if (i % 32 == 0) {
System.out.println("\",");
System.out.print("\t\"");
} else {
System.out.print(" ");
}
}
System.out.println("\",");
System.out.println("};");
}

/**
* Development time utility method.<br>
* Confirms that the specified byte array is equivalent to the hex-dump String lines.
*/
public static void confirmEqual(byte[] expected, String[] hexDataLines) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(hexDataLines.length * 32 + 32);

for (String hexDataLine : hexDataLines) {
byte[] lineData = HexRead.readFromString(hexDataLine);
baos.write(lineData, 0, lineData.length);
}
if (!Arrays.equals(expected, baos.toByteArray())) {
throw new RuntimeException("different");
}
}

/**
* Decompress previously gziped/base64ed data
*
@@ -98,7 +55,7 @@ public final class RawDataUtil {
byte[] base64Bytes = Base64.getDecoder().decode(data);
return IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(base64Bytes)));
}
/**
* Compress raw data for test runs - usually called while debugging :)
*

Loading…
取消
儲存