mirror of https://github.com/apache/poi.git
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
This commit is contained in:
parent
c41dee931f
commit
661c0b66bc
|
@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
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();
|
||||
|
||||
try {
|
||||
|
||||
/**
|
||||
* <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();
|
||||
}
|
||||
// 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);
|
||||
|
||||
|
||||
/**
|
||||
* <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();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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;
|
||||
}
|
||||
de.createDocument(name, mps.toInputStream());
|
||||
}
|
||||
|
||||
try (InputStream is = su.get()) {
|
||||
final POIFSDocumentPath path = event.getPath();
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
}
|
||||
// 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();
|
||||
|
||||
|
||||
/**
|
||||
* Writes the POI file system to a disk file.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
try (OutputStream fos = new FileOutputStream(dstName)) {
|
||||
poiFs.writeFilesystem(fos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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: */
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) + "]:"
|
||||
);
|
||||
|
|
|
@ -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 {
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 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.poifs.filesystem.POIFSFileSystem;
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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[]) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 < amolweb at ya hoo dot com >
|
||||
* @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.);
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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…
Reference in New Issue