merge trunk

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/hemf@1845617 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2018-11-02 18:35:34 +00:00
commit 0e68ef5f84
90 changed files with 2718 additions and 1208 deletions

View File

@ -18,7 +18,7 @@
<classpathentry kind="lib" path="lib/ant-1.10.1.jar"/>
<classpathentry kind="lib" path="lib/ant-launcher-1.10.1.jar"/>
<classpathentry kind="lib" path="lib/log4j-1.2.17.jar"/>
<classpathentry exported="true" kind="lib" path="ooxml-lib/xmlbeans-3.0.1.jar" sourcepath="ooxml-lib/xmlbeans-3.0.1.jar"/>
<classpathentry exported="true" kind="lib" path="ooxml-lib/xmlbeans-3.0.2.jar" sourcepath="ooxml-lib/xmlbeans-3.0.2.jar"/>
<classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/>
<classpathentry kind="lib" path="lib/junit-4.12.jar"/>
<classpathentry kind="lib" path="ooxml-lib/curvesapi-1.05.jar"/>
@ -30,13 +30,16 @@
<classpathentry exported="true" kind="lib" path="compile-lib/slf4j-api-1.7.25.jar"/>
<classpathentry kind="lib" path="compile-lib/bcpkix-jdk15on-1.60.jar"/>
<classpathentry kind="lib" path="compile-lib/bcprov-ext-jdk15on-1.60.jar"/>
<classpathentry kind="lib" path="ooxml-testlib/reflections.jar"/>
<classpathentry kind="lib" path="ooxml-testlib/guava.jar"/>
<classpathentry kind="lib" path="ooxml-testlib/javassist.jar"/>
<classpathentry exported="true" kind="lib" path="compile-lib/xmlsec-2.1.0.jar"/>
<classpathentry exported="true" kind="lib" path="lib/commons-codec-1.11.jar"/>
<classpathentry exported="true" kind="lib" path="lib/commons-logging-1.2.jar"/>
<classpathentry exported="true" kind="lib" path="lib/commons-collections4-4.2.jar"/>
<classpathentry kind="lib" path="lib/commons-math3-3.6.1.jar"/>
<classpathentry kind="lib" path="lib/xmlunit-core-2.5.1.jar"/>
<classpathentry kind="lib" path="lib/mockito-core-2.13.0.jar"/>
<classpathentry kind="lib" path="lib/mockito-core-2.21.0.jar"/>
<classpathentry kind="lib" path="lib/byte-buddy-1.7.9.jar"/>
<classpathentry kind="lib" path="lib/byte-buddy-agent-1.7.9.jar"/>
<classpathentry kind="lib" path="lib/objenesis-2.6.jar"/>

1
.gitignore vendored
View File

@ -11,6 +11,7 @@ log*.*
forrest.properties
compile-lib/
ooxml-lib/
ooxml-testlib/
# Eclipse
/bin

View File

@ -225,7 +225,7 @@ project('ooxml') {
compileJava.dependsOn 'ant-compile-ooxml-xsds'
dependencies {
compile 'org.apache.xmlbeans:xmlbeans:3.0.1'
compile 'org.apache.xmlbeans:xmlbeans:3.0.2'
compile 'org.apache.commons:commons-collections4:4.2'
compile 'org.apache.commons:commons-math3:3.6.1'
compile 'org.apache.commons:commons-compress:1.18'

View File

@ -213,9 +213,9 @@ under the License.
<property name="ooxml.curvesapi.jar" location="${ooxml.lib}/curvesapi-1.05.jar"/>
<property name="ooxml.curvesapi.url"
value="${repository.m2}/maven2/com/github/virtuald/curvesapi/1.05/curvesapi-1.05.jar"/>
<property name="ooxml.xmlbeans.jar" location="${ooxml.lib}/xmlbeans-3.0.1.jar"/>
<property name="ooxml.xmlbeans.jar" location="${ooxml.lib}/xmlbeans-3.0.2.jar"/>
<property name="ooxml.xmlbeans.url"
value="https://repository.apache.org/content/repositories/releases/org/apache/xmlbeans/xmlbeans/3.0.1/xmlbeans-3.0.1.jar"/>
value="https://repository.apache.org/content/repositories/releases/org/apache/xmlbeans/xmlbeans/3.0.2/xmlbeans-3.0.2.jar"/>
<property name="ooxml.commons-compress.jar" location="${main.lib}/commons-compress-1.18.jar"/>
<property name="ooxml.commons-compress.url"
value="${repository.m2}/maven2/org/apache/commons/commons-compress/1.18/commons-compress-1.18.jar"/>
@ -289,7 +289,7 @@ under the License.
<!-- build and distro settings -->
<property name="jar.name" value="poi"/>
<property name="build.site" location="build/site"/>
<property name="javadocs.report.dir" location="${build.site}/apidocs"/>
<property name="javadocs.report.dir" location="${build.site}/apidocs/dev"/>
<property name="dist.dir" location="build/dist"/>
<property name="halt.on.test.failure" value="true"/>
@ -671,6 +671,7 @@ under the License.
<include name="curvesapi-1.04.jar"/>
<include name="xmlbeans-2.*.jar"/>
<include name="xmlbeans-3.0.0.jar"/>
<include name="xmlbeans-3.0.1.jar"/>
</fileset>
<fileset dir="${compile.lib}">
<include name="xercesImpl-*.jar"/>
@ -1798,9 +1799,11 @@ under the License.
<fail message="Apache Forrest is not installed."/>
</target>
<target name="docs" depends="init, -check-forrest-installed, -check-docs, javadocs"
unless="main.docs.notRequired" description="Builds the POI website">
<target name="docs" depends="init, -check-forrest-installed, -check-docs, javadocs, -forrest-docs"
unless="main.docs.notRequired"
description="Builds the POI website" />
<target name="-forrest-docs" depends="-check-forrest-installed, -check-docs"
unless="main.docs.notRequired" description="Builds the HTML pages of the POI website">
<exec executable="${env.FORREST_HOME}/bin/forrest" osfamily="unix"/>
<exec executable="cmd" osfamily="windows">
<arg value="/c"/>
@ -1817,9 +1820,10 @@ under the License.
</touch>
</target>
<!-- Generates the API documentation. -->
<!-- Generates the latest/development API documentation. -->
<target name="javadocs"
description="Generates the API documentation">
<echo message="Generating latest Javadocs in ${javadocs.report.dir}"/>
<javadoc verbose="false" author="true" destdir="${javadocs.report.dir}"
windowtitle="POI API Documentation" use="true" version="true"
maxmemory="384M" additionalparam="-notimestamp" locale="en_US"
@ -2035,7 +2039,7 @@ under the License.
<packageset dir="@{src}" defaultexcludes="yes">
<include name="org/apache/poi/**"/>
</packageset>
<link offline="true" href="https://poi.apache.org/apidocs" packagelistLoc="${javadocs.report.dir}"/>
<link offline="true" href="https://poi.apache.org/apidocs/dev" packagelistLoc="${javadocs.report.dir}"/>
</javadoc>
<jar destfile="${dist.dir}/maven/@{dest}/@{dest}-${version.id}-javadoc.jar"
manifest="build/poi-manifest.mf">

View File

@ -610,7 +610,24 @@ dashboardView("P/POI-new") {
//lastSuccessDescription()
jacoco()
}
description("Jobs related to building/testing Apache POI")
description("<table>\n" +
" <tr>\n" +
" <td><img src=\"https://poi.apache.org/images/project-header.png\" /></td>\n" +
" <td> \n" +
" <p>Apache POI - the Java API for Microsoft Documents</p>\n" +
" <p><b>Most of the POI Jobs are automatically generated by Jenkins Job DSL\n" +
" at <a href=\"https://svn.apache.org/repos/asf/poi/trunk/jenkins\">https://svn.apache.org/repos/asf/poi/trunk/jenkins</a>,<br/>\n" +
" see <a href=\"https://github.com/jenkinsci/job-dsl-plugin/wiki\">https://github.com/jenkinsci/job-dsl-plugin/wiki</a>\n" +
" for more details about the DSL.</b>\n" +
" </p>\n" +
" <p>\n" +
" <b><a href=\"job/POI-DSL-1.8/lastSuccessfulBuild/findbugsResult/\" target=\"_blank\">Findbugs report of latest build</a></b> -\n" +
" <b><a href=\"https://builds.apache.org/analysis/dashboard?id=org.apache.poi%3Apoi-parent&did=1\" target=\"_blank\">Sonar reports</a></b> -\n" +
" <b><a href=\"job/POI-DSL-1.8/lastSuccessfulBuild/artifact/build/coverage/index.html\" target=\"_blank\">Coverage of latest build</a></b>\n" +
" </p>\n" +
" </td>\n" +
" </tr>\n" +
"</table>")
filterBuildQueue(false)
filterExecutors(false)

View File

@ -62,7 +62,7 @@
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>3.0.1</version>
<version>3.0.2</version>
</dependency>
</dependencies>
</project>

View File

@ -72,7 +72,7 @@
<sonar.scm.disabled>true</sonar.scm.disabled>
<!-- define some of the third-party or plugin-versions globally to use the same in all modules -->
<xmlbeans.version>3.0.1</xmlbeans.version>
<xmlbeans.version>3.0.2</xmlbeans.version>
<junit.version>4.12</junit.version>
<xmlunit.version>2.5.1</xmlunit.version>
<mockito.version>2.13.0</mockito.version>

View File

@ -142,13 +142,13 @@ import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
public class AddDimensionedImage {
// Four constants that determine how - and indeed whether - the rows
// and columns an image may overlie should be expanded to accomodate that
// 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 accomodate the image if it is not already larger. The image will
// 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 accomodate the image if it is not already larger. The image
// 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
@ -266,7 +266,7 @@ public class AddDimensionedImage {
}
// Call methods to calculate how the image and sheet should be
// manipulated to accomodate the image; columns and then rows.
// manipulated to accommodate the image; columns and then rows.
colClientAnchorDetail = this.fitImageToColumns(sheet, colNumber,
reqImageWidthMM, resizeBehaviour);
rowClientAnchorDetail = this.fitImageToRows(sheet, rowNumber,
@ -312,7 +312,7 @@ public class AddDimensionedImage {
}
/**
* Determines whether the sheets columns should be re-sized to accomodate
* 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
@ -348,7 +348,7 @@ public class AddDimensionedImage {
colWidthMM = ConvertImageUnits.widthUnits2Millimetres(
(short)sheet.getColumnWidth(colNumber));
// Check that the column's width will accomodate the image at the
// 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
@ -396,7 +396,7 @@ public class AddDimensionedImage {
}
/**
* Determines whether the sheet's row should be re-sized to accomodate
* 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
@ -436,7 +436,7 @@ public class AddDimensionedImage {
// Get the row's height in millimetres
double rowHeightMM = row.getHeightInPoints() / ConvertImageUnits.POINTS_PER_MILLIMETRE;
// Check that the row's height will accomodate the image at the required
// 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.

View File

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

View File

@ -202,13 +202,13 @@ import org.apache.poi.util.IOUtils;
public class AddDimensionedImage {
// Four constants that determine how - and indeed whether - the rows
// and columns an image may overlie should be expanded to accomodate that
// 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 accomodate the image if it is not already larger. The image will
// 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 accomodate the image if it is not already larger. The image
// 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
@ -348,7 +348,7 @@ public class AddDimensionedImage {
}
// Call methods to calculate how the image and sheet should be
// manipulated to accomodate the image; columns and then rows.
// manipulated to accommodate the image; columns and then rows.
colClientAnchorDetail = this.fitImageToColumns(sheet, colNumber,
reqImageWidthMM, resizeBehaviour);
rowClientAnchorDetail = this.fitImageToRows(sheet, rowNumber,
@ -440,7 +440,7 @@ public class AddDimensionedImage {
colWidthMM = ConvertImageUnits.widthUnits2Millimetres(
(short)sheet.getColumnWidth(colNumber));
// Check that the column's width will accomodate the image at the
// 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
@ -500,7 +500,7 @@ public class AddDimensionedImage {
}
/**
* Determines whether the sheets row should be re-sized to accomodate
* Determines whether the sheets 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
* a ClientAnchor that will fix the image on the sheet and establish
@ -542,7 +542,7 @@ public class AddDimensionedImage {
// Get the row's height in millimetres
rowHeightMM = row.getHeightInPoints() / ConvertImageUnits.POINTS_PER_MILLIMETRE;
// Check that the row's height will accomodate the image at the required
// 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.

View File

@ -44,8 +44,8 @@ public class NewLinesInCells {
cs.setWrapText(true);
cell.setCellStyle(cs);
//increase row height to accomodate two lines of text
row.setHeightInPoints((2 * sheet.getDefaultRowHeightInPoints()));
//increase row height to accommodate two lines of text
row.setHeightInPoints(2 * sheet.getDefaultRowHeightInPoints());
//adjust column width to fit the content
sheet.autoSizeColumn(2);
@ -55,5 +55,4 @@ public class NewLinesInCells {
}
}
}
}

View File

@ -33,6 +33,7 @@ import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.hpsf.PropertySet;
import org.apache.poi.hpsf.PropertySetFactory;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.hpsf.WritingNotSupportedException;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.crypt.cryptoapi.CryptoAPIDecryptor;
@ -176,6 +177,8 @@ public abstract class POIDocument implements Closeable {
*
* @param setName The property to read
* @return The value of the given property or null if it wasn't found.
*
* @throws IOException If retrieving properties fails
*/
@SuppressWarnings("WeakerAccess")
protected PropertySet getPropertySet(String setName) throws IOException {
@ -189,6 +192,8 @@ public abstract class POIDocument implements Closeable {
* @param setName The property to read
* @param encryptionInfo the encryption descriptor in case of cryptoAPI encryption
* @return The value of the given property or null if it wasn't found.
*
* @throws IOException If retrieving properties fails
*/
@SuppressWarnings("WeakerAccess")
protected PropertySet getPropertySet(String setName, EncryptionInfo encryptionInfo) throws IOException {
@ -305,7 +310,8 @@ public abstract class POIDocument implements Closeable {
}
/**
* Writes out a given ProperySet
* Writes out a given PropertySet
*
* @param name the (POIFS Level) name of the property to write
* @param set the PropertySet to write out
* @param outFS the NPOIFSFileSystem to write the property into
@ -326,7 +332,7 @@ public abstract class POIDocument implements Closeable {
outFS.createOrUpdateDocument(bIn, name);
logger.log(POILogger.INFO, "Wrote property set " + name + " of size " + data.length);
} catch(org.apache.poi.hpsf.WritingNotSupportedException wnse) {
} catch(WritingNotSupportedException ignored) {
logger.log( POILogger.ERROR, "Couldn't write property set with name " + name + " as not supported by HPSF yet");
}
}
@ -468,6 +474,8 @@ public abstract class POIDocument implements Closeable {
/**
* @return the encryption info if the document is encrypted, otherwise {@code null}
*
* @throws IOException If retrieving the encryption information fails
*/
public EncryptionInfo getEncryptionInfo() throws IOException {
return null;

View File

@ -68,13 +68,15 @@ public enum FontFamily {
}
return null;
}
/**
* Get FontFamily from combined native id
*
* @param pitchAndFamily The PitchFamily to decode.
*
* @return The resulting FontFamily
*/
public static FontFamily valueOfPitchFamily(byte pitchAndFamily) {
return valueOf(pitchAndFamily >>> 4);
}
}
}

View File

@ -59,6 +59,11 @@ public enum FontPitch {
* Combine pitch and family to native id
*
* @see <a href="https://msdn.microsoft.com/en-us/library/dd145037.aspx">LOGFONT structure</a>
*
* @param pitch The pitch-value, cannot be null
* @param family The family-value, cannot be null
*
* @return The resulting combined byte-value with pitch and family encoded into one byte
*/
public static byte getNativeId(FontPitch pitch, FontFamily family) {
return (byte)(pitch.getNativeId() | (family.getFlag() << 4));
@ -66,9 +71,12 @@ public enum FontPitch {
/**
* Get FontPitch from native id
*
* @param pitchAndFamily The combined byte value for pitch and family
*
* @return The resulting FontPitch enumeration value
*/
public static FontPitch valueOfPitchFamily(byte pitchAndFamily) {
return valueOf(pitchAndFamily & 0x3);
}
}

View File

@ -65,6 +65,8 @@ public final class OLE2ExtractorFactory {
* Should this thread prefer event based over usermodel based extractors?
* (usermodel extractors tend to be more accurate, but use more memory)
* Default is false.
*
* @return true if event extractors should be preferred in the current thread, fals otherwise.
*/
public static boolean getThreadPrefersEventExtractors() {
return threadPreferEventExtractors.get();
@ -74,6 +76,8 @@ public final class OLE2ExtractorFactory {
* Should all threads prefer event based over usermodel based extractors?
* (usermodel extractors tend to be more accurate, but use more memory)
* Default is to use the thread level setting, which defaults to false.
*
* @return true if event extractors should be preferred in all threads, fals otherwise.
*/
public static Boolean getAllThreadsPreferEventExtractors() {
return allPreferEventExtractors;
@ -82,6 +86,8 @@ public final class OLE2ExtractorFactory {
/**
* Should this thread prefer event based over usermodel based extractors?
* Will only be used if the All Threads setting is null.
*
* @param preferEventExtractors If this threads should prefer event based extractors.
*/
public static void setThreadPrefersEventExtractors(boolean preferEventExtractors) {
threadPreferEventExtractors.set(preferEventExtractors);
@ -90,6 +96,8 @@ public final class OLE2ExtractorFactory {
/**
* Should all threads prefer event based over usermodel based extractors?
* If set, will take preference over the Thread level setting.
*
* @param preferEventExtractors If all threads should prefer event based extractors.
*/
public static void setAllThreadsPreferEventExtractors(Boolean preferEventExtractors) {
allPreferEventExtractors = preferEventExtractors;
@ -98,6 +106,8 @@ public final class OLE2ExtractorFactory {
/**
* Should this thread use event based extractors is available?
* Checks the all-threads one first, then thread specific.
*
* @return If the current thread should use event based extractors.
*/
public static boolean getPreferEventExtractor() {
if(allPreferEventExtractors != null) {
@ -155,6 +165,16 @@ public final class OLE2ExtractorFactory {
* Create the Extractor, if possible. Generally needs the Scratchpad jar.
* Note that this won't check for embedded OOXML resources either, use
* {@link org.apache.poi.ooxml.extractor.ExtractorFactory} for that.
*
* @param poifsDir The {@link DirectoryNode} pointing to a document.
*
* @return The resulting {@link POITextExtractor}, an exception is thrown if
* no TextExtractor can be created for some reason.
*
* @throws IOException If converting the {@link DirectoryNode} into a HSSFWorkbook fails
* @throws OldFileFormatException If the {@link DirectoryNode} points to a format of
* an unsupported version of Excel.
* @throws IllegalArgumentException If creating the Extractor fails
*/
public static POITextExtractor createExtractor(DirectoryNode poifsDir) throws IOException {
// Look for certain entries in the stream, to figure it
@ -193,11 +213,17 @@ public final class OLE2ExtractorFactory {
* If there are no embedded documents, you'll get back an
* empty array. Otherwise, you'll get one open
* {@link POITextExtractor} for each embedded file.
*
* @param ext The extractor to look at for embedded documents
*
* @return An array of resulting extractors. Empty if no embedded documents are found.
*
* @throws IOException If converting the {@link DirectoryNode} into a HSSFWorkbook fails
* @throws OldFileFormatException If the {@link DirectoryNode} points to a format of
* an unsupported version of Excel.
* @throws IllegalArgumentException If creating the Extractor fails
*/
@SuppressWarnings("unused")
public static POITextExtractor[] getEmbededDocsTextExtractors(POIOLE2TextExtractor ext)
throws IOException
{
public static POITextExtractor[] getEmbededDocsTextExtractors(POIOLE2TextExtractor ext) throws IOException {
// All the embedded directories we spotted
List<Entry> dirs = new ArrayList<>();
// For anything else not directly held in as a POIFS directory
@ -237,13 +263,12 @@ public final class OLE2ExtractorFactory {
ArrayList<POITextExtractor> e = new ArrayList<>();
for (Entry dir : dirs) {
e.add(createExtractor(
(DirectoryNode) dir
e.add(createExtractor((DirectoryNode) dir
));
}
for (InputStream nonPOIF : nonPOIFS) {
for (InputStream stream : nonPOIFS) {
try {
e.add(createExtractor(nonPOIF));
e.add(createExtractor(stream));
} catch (Exception xe) {
// Ignore, invalid format
LOGGER.log(POILogger.WARN, xe);

View File

@ -248,12 +248,14 @@ public class Property {
/**
* Returns the property's size in bytes. This is always a multiple of 4.
*
* @param property The integer property to check
*
* @return the property's size in bytes
*
* @exception WritingNotSupportedException if HPSF does not yet support the
* property's variant type.
*/
protected int getSize(int codepage) throws WritingNotSupportedException
protected int getSize(int property) throws WritingNotSupportedException
{
int length = Variant.getVariantLength(type);
if (length >= 0 || type == Variant.VT_EMPTY) {
@ -269,16 +271,16 @@ public class Property {
if (type == Variant.VT_LPSTR || type == Variant.VT_LPWSTR) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
length = write(bos, codepage) - 2*LittleEndianConsts.INT_SIZE;
length = write(bos, property) - 2*LittleEndianConsts.INT_SIZE;
/* Pad to multiples of 4. */
length += (4 - (length & 0x3)) & 0x3;
return length;
} catch (IOException e) {
throw new WritingNotSupportedException(type, value);
throw new WritingNotSupportedException(type, this.value);
}
}
throw new WritingNotSupportedException(type, value);
throw new WritingNotSupportedException(type, this.value);
}

View File

@ -31,6 +31,15 @@ import org.apache.poi.util.Internal;
@SuppressWarnings("unused")
@Internal
public class HSSFWorkbookFactory extends WorkbookFactory {
/**
* Create a new empty Workbook
*
* @return The created workbook
*/
public static HSSFWorkbook createWorkbook() {
return new HSSFWorkbook();
}
/**
* Creates a HSSFWorkbook from the given NPOIFSFileSystem<p>
* Note that in order to properly release resources the

View File

@ -20,9 +20,19 @@ package org.apache.poi.poifs.macros;
import static org.apache.poi.util.StringUtil.endsWithIgnoreCase;
import static org.apache.poi.util.StringUtil.startsWithIgnoreCase;
import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -39,6 +49,8 @@ import org.apache.poi.util.CodePageUtil;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.RLEDecompressingInputStream;
import org.apache.poi.util.StringUtil;
@ -56,6 +68,10 @@ import org.apache.poi.util.StringUtil;
* @since 3.15-beta2
*/
public class VBAMacroReader implements Closeable {
private static final POILogger LOGGER = POILogFactory.getLogger(VBAMacroReader.class);
//arbitrary limit on size of strings to read, etc.
private static final int MAX_STRING_LENGTH = 20000;
protected static final String VBA_PROJECT_OOXML = "vbaProject.bin";
protected static final String VBA_PROJECT_POIFS = "VBA";
@ -111,8 +127,13 @@ public class VBAMacroReader implements Closeable {
public Map<String, Module> readMacroModules() throws IOException {
final ModuleMap modules = new ModuleMap();
//ascii -> unicode mapping for module names
//preserve insertion order
final Map<String, String> moduleNameMap = new LinkedHashMap<>();
findMacros(fs.getRoot(), modules);
findProjectProperties(fs.getRoot(), modules);
findModuleNameMap(fs.getRoot(), moduleNameMap, modules);
findProjectProperties(fs.getRoot(), moduleNameMap, modules);
Map<String, Module> moduleSources = new HashMap<>();
for (Map.Entry<String, ModuleImpl> entry : modules.entrySet()) {
@ -327,19 +348,30 @@ public class VBAMacroReader implements Closeable {
}
}
protected void findProjectProperties(DirectoryNode node, ModuleMap modules) throws IOException {
protected void findProjectProperties(DirectoryNode node, Map<String, String> moduleNameMap, ModuleMap modules) throws IOException {
for (Entry entry : node) {
if ("project".equalsIgnoreCase(entry.getName())) {
DocumentNode document = (DocumentNode)entry;
DocumentInputStream dis = new DocumentInputStream(document);
readProjectProperties(dis, modules);
} else {
for (Entry child : node) {
if (child instanceof DirectoryNode) {
findProjectProperties((DirectoryNode)child, modules);
}
try(DocumentInputStream dis = new DocumentInputStream(document)) {
readProjectProperties(dis, moduleNameMap, modules);
return;
}
} else if (entry instanceof DirectoryNode) {
findProjectProperties((DirectoryNode)entry, moduleNameMap, modules);
}
}
}
protected void findModuleNameMap(DirectoryNode node, Map<String, String> moduleNameMap, ModuleMap modules) throws IOException {
for (Entry entry : node) {
if ("projectwm".equalsIgnoreCase(entry.getName())) {
DocumentNode document = (DocumentNode)entry;
try(DocumentInputStream dis = new DocumentInputStream(document)) {
readNameMapRecords(dis, moduleNameMap, modules.charset);
return;
}
} else if (entry.isDirectoryEntry()) {
findModuleNameMap((DirectoryNode)entry, moduleNameMap, modules);
}
}
}
@ -426,10 +458,18 @@ public class VBAMacroReader implements Closeable {
private static class ASCIIUnicodeStringPair {
private final String ascii;
private final String unicode;
private final int pushbackRecordId;
ASCIIUnicodeStringPair(String ascii, int pushbackRecordId) {
this.ascii = ascii;
this.unicode = "";
this.pushbackRecordId = pushbackRecordId;
}
ASCIIUnicodeStringPair(String ascii, String unicode) {
this.ascii = ascii;
this.unicode = unicode;
pushbackRecordId = -1;
}
private String getAscii() {
@ -439,6 +479,10 @@ public class VBAMacroReader implements Closeable {
private String getUnicode() {
return unicode;
}
private int getPushbackRecordId() {
return pushbackRecordId;
}
}
private void processDirStream(Entry dir, ModuleMap modules) throws IOException {
@ -447,7 +491,7 @@ public class VBAMacroReader implements Closeable {
try (DocumentInputStream dis = new DocumentInputStream(dirDocumentNode)) {
String streamName = null;
int recordId = 0;
boolean inReferenceTwiddled = false;
try (RLEDecompressingInputStream in = new RLEDecompressingInputStream(dis)) {
while (true) {
recordId = in.readShort();
@ -485,7 +529,27 @@ public class VBAMacroReader implements Closeable {
if (dirState.equals(DIR_STATE.INFORMATION_RECORD)) {
dirState = DIR_STATE.REFERENCES_RECORD;
}
readStringPair(in, modules.charset, REFERENCE_NAME_RESERVED);
ASCIIUnicodeStringPair stringPair = readStringPair(in,
modules.charset, REFERENCE_NAME_RESERVED, false);
if (stringPair.getPushbackRecordId() == -1) {
break;
}
//Special handling for when there's only an ascii string and a REFERENCED_REGISTERED
//record that follows.
//See https://github.com/decalage2/oletools/blob/master/oletools/olevba.py#L1516
//and https://github.com/decalage2/oletools/pull/135 from (@c1fe)
if (stringPair.getPushbackRecordId() != RecordType.REFERENCE_REGISTERED.id) {
throw new IllegalArgumentException("Unexpected reserved character. "+
"Expected "+Integer.toHexString(REFERENCE_NAME_RESERVED)
+ " or "+Integer.toHexString(RecordType.REFERENCE_REGISTERED.id)+
" not: "+Integer.toHexString(stringPair.getPushbackRecordId()));
}
//fall through!
case REFERENCE_REGISTERED:
//REFERENCE_REGISTERED must come immediately after
//REFERENCE_NAME to allow for fall through in special case of bug 62625
int recLength = in.readInt();
trySkip(in, recLength);
break;
case MODULE_DOC_STRING:
int modDocStringLength = in.readInt();
@ -546,19 +610,105 @@ public class VBAMacroReader implements Closeable {
}
}
private ASCIIUnicodeStringPair readStringPair(RLEDecompressingInputStream in, Charset charset, int reservedByte) throws IOException {
private ASCIIUnicodeStringPair readStringPair(RLEDecompressingInputStream in,
Charset charset, int reservedByte) throws IOException {
return readStringPair(in, charset, reservedByte, true);
}
private ASCIIUnicodeStringPair readStringPair(RLEDecompressingInputStream in,
Charset charset, int reservedByte,
boolean throwOnUnexpectedReservedByte) throws IOException {
int nameLength = in.readInt();
String ascii = readString(in, nameLength, charset);
int reserved = in.readShort();
if (reserved != reservedByte) {
throw new IOException("Expected "+Integer.toHexString(reservedByte)+ "after name before Unicode name, but found: " +
Integer.toHexString(reserved));
if (throwOnUnexpectedReservedByte) {
throw new IOException("Expected " + Integer.toHexString(reservedByte) +
"after name before Unicode name, but found: " +
Integer.toHexString(reserved));
} else {
return new ASCIIUnicodeStringPair(ascii, reserved);
}
}
int unicodeNameRecordLength = in.readInt();
String unicode = readUnicodeString(in, unicodeNameRecordLength);
return new ASCIIUnicodeStringPair(ascii, unicode);
}
protected void readNameMapRecords(InputStream is,
Map<String, String> moduleNames, Charset charset) throws IOException {
//see 2.3.3 PROJECTwm Stream: Module Name Information
//multibytecharstring
String mbcs = null;
String unicode = null;
//arbitrary sanity threshold
final int maxNameRecords = 10000;
int records = 0;
while (++records < maxNameRecords) {
try {
int b = IOUtils.readByte(is);
//check for two 0x00 that mark end of record
if (b == 0) {
b = IOUtils.readByte(is);
if (b == 0) {
return;
}
}
mbcs = readMBCS(b, is, charset, MAX_STRING_LENGTH);
} catch (EOFException e) {
return;
}
try {
unicode = readUnicode(is, MAX_STRING_LENGTH);
} catch (EOFException e) {
return;
}
if (mbcs.trim().length() > 0 && unicode.trim().length() > 0) {
moduleNames.put(mbcs, unicode);
}
}
if (records >= maxNameRecords) {
LOGGER.log(POILogger.WARN, "Hit max name records to read ("+maxNameRecords+"). Stopped early.");
}
}
private static String readUnicode(InputStream is, int maxLength) throws IOException {
//reads null-terminated unicode string
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int b0 = IOUtils.readByte(is);
int b1 = IOUtils.readByte(is);
int read = 2;
while ((b0 + b1) != 0 && read < maxLength) {
bos.write(b0);
bos.write(b1);
b0 = IOUtils.readByte(is);
b1 = IOUtils.readByte(is);
read += 2;
}
if (read >= maxLength) {
LOGGER.log(POILogger.WARN, "stopped reading unicode name after "+read+" bytes");
}
return new String (bos.toByteArray(), StandardCharsets.UTF_16LE);
}
private static String readMBCS(int firstByte, InputStream is, Charset charset, int maxLength) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len = 0;
int b = firstByte;
while (b > 0 && len < maxLength) {
++len;
bos.write(b);
b = IOUtils.readByte(is);
}
return new String(bos.toByteArray(), charset);
}
/**
* Read <tt>length</tt> bytes of MBCS (multi-byte character set) characters from the stream
@ -570,7 +720,7 @@ public class VBAMacroReader implements Closeable {
* @throws IOException If reading from the stream fails
*/
private static String readString(InputStream stream, int length, Charset charset) throws IOException {
byte[] buffer = IOUtils.safelyAllocate(length, 20000);
byte[] buffer = IOUtils.safelyAllocate(length, MAX_STRING_LENGTH);
int bytesRead = IOUtils.readFully(stream, buffer);
if (bytesRead != length) {
throw new IOException("Tried to read: "+length +
@ -579,7 +729,8 @@ public class VBAMacroReader implements Closeable {
return new String(buffer, 0, length, charset);
}
protected void readProjectProperties(DocumentInputStream dis, ModuleMap modules) throws IOException {
protected void readProjectProperties(DocumentInputStream dis,
Map<String, String> moduleNameMap, ModuleMap modules) throws IOException {
InputStreamReader reader = new InputStreamReader(dis, modules.charset);
StringBuilder builder = new StringBuilder();
char[] buffer = new char[512];
@ -588,6 +739,9 @@ public class VBAMacroReader implements Closeable {
builder.append(buffer, 0, read);
}
String properties = builder.toString();
//the module name map names should be in exactly the same order
//as the module names here. See 2.3.3 PROJECTwm Stream.
//At some point, we might want to enforce that.
for (String line : properties.split("\r\n|\n\r")) {
if (!line.startsWith("[")) {
String[] tokens = line.split("=");
@ -595,28 +749,46 @@ public class VBAMacroReader implements Closeable {
&& tokens[1].startsWith("\"") && tokens[1].endsWith("\"")) {
// Remove any double quotes
tokens[1] = tokens[1].substring(1, tokens[1].length() - 1);
}
if ("Document".equals(tokens[0])) {
if ("Document".equals(tokens[0]) && tokens.length > 1) {
String mn = tokens[1].substring(0, tokens[1].indexOf("/&H"));
ModuleImpl module = modules.get(mn);
module.moduleType = ModuleType.Document;
} else if ("Module".equals(tokens[0])) {
ModuleImpl module = modules.get(tokens[1]);
module.moduleType = ModuleType.Module;
} else if ("Class".equals(tokens[0])) {
ModuleImpl module = modules.get(tokens[1]);
module.moduleType = ModuleType.Class;
ModuleImpl module = getModule(mn, moduleNameMap, modules);
if (module != null) {
module.moduleType = ModuleType.Document;
} else {
LOGGER.log(POILogger.WARN, "couldn't find module with name: "+mn);
}
} else if ("Module".equals(tokens[0]) && tokens.length > 1) {
ModuleImpl module = getModule(tokens[1], moduleNameMap, modules);
if (module != null) {
module.moduleType = ModuleType.Module;
} else {
LOGGER.log(POILogger.WARN, "couldn't find module with name: "+tokens[1]);
}
} else if ("Class".equals(tokens[0]) && tokens.length > 1) {
ModuleImpl module = getModule(tokens[1], moduleNameMap, modules);
if (module != null) {
module.moduleType = ModuleType.Class;
} else {
LOGGER.log(POILogger.WARN, "couldn't find module with name: "+tokens[1]);
}
}
}
}
}
//can return null!
private ModuleImpl getModule(String moduleName, Map<String, String> moduleNameMap, ModuleMap moduleMap) {
if (moduleNameMap.containsKey(moduleName)) {
return moduleMap.get(moduleNameMap.get(moduleName));
}
return moduleMap.get(moduleName);
}
private String readUnicodeString(RLEDecompressingInputStream in, int unicodeNameRecordLength) throws IOException {
byte[] buffer = IOUtils.safelyAllocate(unicodeNameRecordLength, 20000);
byte[] buffer = IOUtils.safelyAllocate(unicodeNameRecordLength, MAX_STRING_LENGTH);
int bytesRead = IOUtils.readFully(in, buffer);
if (bytesRead != unicodeNameRecordLength) {
throw new EOFException();
}
return new String(buffer, StringUtil.UTF16LE);
}

View File

@ -50,6 +50,7 @@ public class CellDateFormatter extends CellFormatter {
private int hStart = -1;
private int hLen;
@Override
public String handlePart(Matcher m, String part, CellFormatType type,
StringBuffer desc) {

View File

@ -16,10 +16,7 @@
==================================================================== */
package org.apache.poi.ss.format;
import org.apache.poi.ss.format.CellFormatPart.PartHandler;
import java.util.Locale;
import java.util.regex.Matcher;
/**
* This class implements printing out text.
@ -38,15 +35,12 @@ public class CellTextFormatter extends CellFormatter {
final int[] numPlaces = new int[1];
desc = CellFormatPart.parseFormat(format, CellFormatType.TEXT,
new PartHandler() {
public String handlePart(Matcher m, String part,
CellFormatType type, StringBuffer desc) {
if (part.equals("@")) {
numPlaces[0]++;
return "\u0000";
}
return null;
(m, part, type, desc) -> {
if (part.equals("@")) {
numPlaces[0]++;
return "\u0000";
}
return null;
}).toString();
// Remember the "@" positions in last-to-first order (to make insertion easier)
@ -66,8 +60,8 @@ public class CellTextFormatter extends CellFormatter {
text = text.toUpperCase(Locale.ROOT);
}
toAppendTo.append(desc);
for (int i = 0; i < textPos.length; i++) {
int pos = start + textPos[i];
for (int textPo : textPos) {
int pos = start + textPo;
toAppendTo.replace(pos, pos + 1, text);
}
}

View File

@ -64,6 +64,14 @@ public abstract class BaseFormulaEvaluator implements FormulaEvaluator, Workbook
return _bookEvaluator;
}
/**
* internal use
* @return evaluation workbook
*/
protected EvaluationWorkbook getEvaluationWorkbook() {
return _bookEvaluator.getWorkbook();
}
/**
* Should be called whenever there are major changes (e.g. moving sheets) to input cells
* in the evaluated workbook. If performance is not critical, a single call to this method
@ -208,14 +216,19 @@ public abstract class BaseFormulaEvaluator implements FormulaEvaluator, Workbook
return evaluateFormulaCell(cell);
}
protected static void setCellType(Cell cell, CellValue cv) {
/**
* set the cell type
* @param cell
* @param cv
*/
protected void setCellType(Cell cell, CellValue cv) {
CellType cellType = cv.getCellType();
switch (cellType) {
case BOOLEAN:
case ERROR:
case NUMERIC:
case STRING:
cell.setCellType(cellType);
setCellType(cell, cellType);
return;
case BLANK:
// never happens - blanks eventually get translated to zero
@ -227,6 +240,15 @@ public abstract class BaseFormulaEvaluator implements FormulaEvaluator, Workbook
throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
}
}
/**
* Override if a different variation is needed, e.g. passing the evaluator to the cell method
* @param cell
* @param cellType
*/
protected void setCellType(Cell cell, CellType cellType) {
cell.setCellType(cellType);
}
protected abstract RichTextString createRichTextString(String str);

View File

@ -115,7 +115,7 @@ public final class FunctionEval {
// 47: DVAR
retval[48] = TextFunction.TEXT;
// 49: LINEST
// 50: TREND
retval[50] = new Trend();
// 51: LOGEST
// 52: GROWTH
@ -243,7 +243,8 @@ public final class FunctionEval {
// 247: DB
// 252: FEQUENCY
retval[252] = Frequency.instance;
retval[FunctionID.EXTERNAL_FUNC] = null; // ExternalFunction is a FreeRefFunction, nominally 255
retval[261] = new Errortype();

View File

@ -0,0 +1,81 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.ss.formula.functions;
import org.apache.poi.ss.formula.CacheAreaEval;
import org.apache.poi.ss.formula.eval.EvaluationException;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import java.util.Arrays;
/**
* Implementation of Excel 'Analysis ToolPak' function FREQUENCY()<br>
* Returns a frequency distribution as a vertical array<p>
* <p>
* <b>Syntax</b><br>
* <b>FREQUENCY</b>(<b>data_array</b>, <b>bins_array</b>)<p>
* <p>
* <b>data_array</b> Required. An array of or reference to a set of values for which you want to count frequencies.
* If data_array contains no values, FREQUENCY returns an array of zeros.<br>
* <b>bins_array</b> Required. An array of or reference to intervals into which you want to group the values in data_array.
* If bins_array contains no values, FREQUENCY returns the number of elements in data_array.<br>
*
* @author Yegor Kozlov
*/
public class Frequency extends Fixed2ArgFunction {
public static final Function instance = new Frequency();
private Frequency() {
// enforce singleton
}
public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) {
MatrixFunction.MutableValueCollector collector = new MatrixFunction.MutableValueCollector(false, false);
double[] values;
double[] bins;
try {
values = collector.collectValues(arg0);
bins = collector.collectValues(arg1);
} catch (EvaluationException e) {
return e.getErrorEval();
}
// can bins be not sorted?
//bins = Arrays.stream(bins).sorted().distinct().toArray();
int[] histogram = histogram(values, bins);
NumberEval[] result = Arrays.stream(histogram).boxed().map(NumberEval::new).toArray(NumberEval[]::new);
return new CacheAreaEval(srcRowIndex, srcColumnIndex,
srcRowIndex + result.length - 1, srcColumnIndex, result);
}
static int findBin(double value, double[] bins) {
int idx = Arrays.binarySearch(bins, value);
return idx >= 0 ? idx + 1 : -idx;
}
static int[] histogram(double[] values, double[] bins) {
int[] histogram = new int[bins.length + 1];
for (double val : values) {
histogram[findBin(val, bins) - 1]++;
}
return histogram;
}
}

View File

@ -0,0 +1,377 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
/*
* Notes:
* Duplicate x values don't work most of the time because of the way the
* math library handles multiple regression.
* The math library currently fails when the number of x variables is >=
* the sample size (see https://github.com/Hipparchus-Math/hipparchus/issues/13).
*/
package org.apache.poi.ss.formula.functions;
import org.apache.poi.ss.formula.CacheAreaEval;
import org.apache.poi.ss.formula.eval.AreaEval;
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.MissingArgEval;
import org.apache.poi.ss.formula.eval.NotImplementedException;
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">
* <tr><th>known_y's, known_x's, new_x's</th><td>typically area references, possibly cell references or scalar values</td></tr>
* <tr><th>constant</th><td><b>TRUE</b> or <b>FALSE</b>:
* determines whether the regression line should include an intercept term</td></tr>
* </table><br>
* If <b>known_x's</b> is not given, it is assumed to be the default array {1, 2, 3, ...}
* of the same size as <b>known_y's</b>.<br>
* If <b>new_x's</b> is not given, it is assumed to be the same as <b>known_x's</b><br>
* If <b>constant</b> is omitted, it is assumed to be <b>TRUE</b>
* </p>
*/
public final class Trend implements Function {
MatrixFunction.MutableValueCollector collector = new MatrixFunction.MutableValueCollector(false, false);
private static final class TrendResults {
public double[] vals;
public int resultWidth;
public int resultHeight;
public TrendResults(double[] vals, int resultWidth, int resultHeight) {
this.vals = vals;
this.resultWidth = resultWidth;
this.resultHeight = resultHeight;
}
}
public ValueEval evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
if (args.length < 1 || args.length > 4) {
return ErrorEval.VALUE_INVALID;
}
try {
TrendResults tr = getNewY(args);
ValueEval[] vals = new ValueEval[tr.vals.length];
for (int i = 0; i < tr.vals.length; i++) {
vals[i] = new NumberEval(tr.vals[i]);
}
if (tr.vals.length == 1) {
return vals[0];
}
return new CacheAreaEval(srcRowIndex, srcColumnIndex, srcRowIndex + tr.resultHeight - 1, srcColumnIndex + tr.resultWidth - 1, vals);
} catch (EvaluationException e) {
return e.getErrorEval();
}
}
private static double[][] evalToArray(ValueEval arg) throws EvaluationException {
double[][] ar;
ValueEval eval;
if (arg instanceof MissingArgEval) {
return new double[0][0];
}
if (arg instanceof RefEval) {
RefEval re = (RefEval) arg;
if (re.getNumberOfSheets() > 1) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
eval = re.getInnerValueEval(re.getFirstSheetIndex());
} else {
eval = arg;
}
if (eval == null) {
throw new RuntimeException("Parameter may not be null.");
}
if (eval instanceof AreaEval) {
AreaEval ae = (AreaEval) eval;
int w = ae.getWidth();
int h = ae.getHeight();
ar = new double[h][w];
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
ValueEval ve = ae.getRelativeValue(i, j);
if (!(ve instanceof NumericValueEval)) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
ar[i][j] = ((NumericValueEval)ve).getNumberValue();
}
}
} else if (eval instanceof NumericValueEval) {
ar = new double[1][1];
ar[0][0] = ((NumericValueEval)eval).getNumberValue();
} 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;
}
return array;
}
private static double[] flattenArray(double[][] twoD) {
if (twoD.length < 1) {
return new double[0];
}
double[] oneD = new double[twoD.length * twoD[0].length];
for (int i = 0; i < twoD.length; i++) {
for (int j = 0; j < twoD[0].length; j++) {
oneD[i * twoD[0].length + j] = twoD[i][j];
}
}
return oneD;
}
private static double[][] flattenArrayToRow(double[][] twoD) {
if (twoD.length < 1) {
return new double[0][0];
}
double[][] oneD = new double[twoD.length * twoD[0].length][1];
for (int i = 0; i < twoD.length; i++) {
for (int j = 0; j < twoD[0].length; j++) {
oneD[i * twoD[0].length + j][0] = twoD[i][j];
}
}
return oneD;
}
private static double[][] switchRowsColumns(double[][] array) {
double[][] newArray = new double[array[0].length][array.length];
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[0].length; j++) {
newArray[j][i] = array[i][j];
}
}
return newArray;
}
/**
* Check if all columns in a matrix contain the same values.
* Return true if the number of distinct values in each column is 1.
*
* @param matrix column-oriented matrix. A Row matrix should be transposed to column .
* @return true if all columns contain the same value
*/
private static boolean isAllColumnsSame(double[][] matrix){
if(matrix.length == 0) return false;
boolean[] cols = new boolean[matrix[0].length];
for (int j = 0; j < matrix[0].length; j++) {
double prev = Double.NaN;
for (int i = 0; i < matrix.length; i++) {
double v = matrix[i][j];
if(i > 0 && v != prev) {
cols[j] = true;
break;
}
prev = v;
}
}
boolean allEquals = true;
for (boolean x : cols) {
if(x) {
allEquals = false;
break;
}
};
return allEquals;
}
private static TrendResults getNewY(ValueEval[] args) throws EvaluationException {
double[][] xOrig;
double[][] x;
double[][] yOrig;
double[] y;
double[][] newXOrig;
double[][] newX;
double[][] resultSize;
boolean passThroughOrigin = false;
switch (args.length) {
case 1:
yOrig = evalToArray(args[0]);
xOrig = new double[0][0];
newXOrig = new double[0][0];
break;
case 2:
yOrig = evalToArray(args[0]);
xOrig = evalToArray(args[1]);
newXOrig = new double[0][0];
break;
case 3:
yOrig = evalToArray(args[0]);
xOrig = evalToArray(args[1]);
newXOrig = evalToArray(args[2]);
break;
case 4:
yOrig = evalToArray(args[0]);
xOrig = evalToArray(args[1]);
newXOrig = evalToArray(args[2]);
if (!(args[3] instanceof BoolEval)) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
// The argument in Excel is false when it *should* pass through the origin.
passThroughOrigin = !((BoolEval)args[3]).getBooleanValue();
break;
default:
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
if (yOrig.length < 1) {
throw new EvaluationException(ErrorEval.VALUE_INVALID);
}
y = flattenArray(yOrig);
newX = newXOrig;
if (newXOrig.length > 0) {
resultSize = newXOrig;
} else {
resultSize = new double[1][1];
}
if (y.length == 1) {
/* See comment at top of file
if (xOrig.length > 0 && !(xOrig.length == 1 || xOrig[0].length == 1)) {
throw new EvaluationException(ErrorEval.REF_INVALID);
} else if (xOrig.length < 1) {
x = new double[1][1];
x[0][0] = 1;
} else {
x = new double[1][];
x[0] = flattenArray(xOrig);
if (newXOrig.length < 1) {
resultSize = xOrig;
}
}*/
throw new NotImplementedException("Sample size too small");
} else if (yOrig.length == 1 || yOrig[0].length == 1) {
if (xOrig.length < 1) {
x = getDefaultArrayOneD(y.length);
if (newXOrig.length < 1) {
resultSize = yOrig;
}
} else {
x = xOrig;
if (xOrig[0].length > 1 && yOrig.length == 1) {
x = switchRowsColumns(x);
}
if (newXOrig.length < 1) {
resultSize = xOrig;
}
}
if (newXOrig.length > 0 && (x.length == 1 || x[0].length == 1)) {
newX = flattenArrayToRow(newXOrig);
}
} else {
if (xOrig.length < 1) {
x = getDefaultArrayOneD(y.length);
if (newXOrig.length < 1) {
resultSize = yOrig;
}
} else {
x = flattenArrayToRow(xOrig);
if (newXOrig.length < 1) {
resultSize = xOrig;
}
}
if (newXOrig.length > 0) {
newX = flattenArrayToRow(newXOrig);
}
if (y.length != x.length || yOrig.length != xOrig.length) {
throw new EvaluationException(ErrorEval.REF_INVALID);
}
}
if (newXOrig.length < 1) {
newX = x;
} 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");
}
int resultHeight = resultSize.length;
int resultWidth = resultSize[0].length;
if(isAllColumnsSame(x)){
double[] result = new double[newX.length];
double avg = Arrays.stream(y).average().orElse(0);
for(int i = 0; i < result.length; i++) result[i] = avg;
return new TrendResults(result, resultWidth, resultHeight);
}
OLSMultipleLinearRegression reg = new OLSMultipleLinearRegression();
if (passThroughOrigin) {
reg.setNoIntercept(true);
}
try {
reg.newSampleData(y, x);
} catch (IllegalArgumentException e) {
throw new EvaluationException(ErrorEval.REF_INVALID);
}
double[] par;
try {
par = reg.estimateRegressionParameters();
} catch (SingularMatrixException e) {
throw new NotImplementedException("Singular matrix in input");
}
double[] result = new double[newX.length];
for (int i = 0; i < newX.length; i++) {
result[i] = 0;
if (passThroughOrigin) {
for (int j = 0; j < par.length; j++) {
result[i] += par[j] * newX[i][j];
}
} else {
result[i] = par[0];
for (int j = 1; j < par.length; j++) {
result[i] += par[j] * newX[i][j - 1];
}
}
}
return new TrendResults(result, resultWidth, resultHeight);
}
}

View File

@ -43,7 +43,7 @@ public abstract class RefPtgBase extends OperandPtg {
/**
* YK: subclasses of RefPtgBase are used by the FormulaParser and FormulaEvaluator accross HSSF and XSSF.
* The bit mask should accomodate the maximum number of avaiable columns, i.e. 0x3FFF.
* The bit mask should accommodate the maximum number of avaiable columns, i.e. 0x3FFF.
*
* @see org.apache.poi.ss.SpreadsheetVersion
*/

View File

@ -1006,7 +1006,10 @@ public interface Sheet extends Iterable<Row> {
/**
* Sets array formula to specified region for result.
*
* <p>
* Note if there are shared formulas this will invalidate any
* {@link FormulaEvaluator} instances based on this workbook
*</p>
* @param formula text representation of the formula
* @param range Region of array formula for result.
* @return the {@link CellRange} of cells affected by this change

View File

@ -43,6 +43,24 @@ import org.apache.poi.util.Removal;
* by auto-detecting from the supplied input.
*/
public class WorkbookFactory {
/**
* Create a new empty Workbook, either XSSF or HSSF depending
* on the parameter
*
* @param xssf If an XSSFWorkbook or a HSSFWorkbook should be created
*
* @return The created workbook
*
* @throws IOException if an error occurs while reading the data
*/
public static Workbook create(boolean xssf) throws IOException {
if(xssf) {
return createXSSFWorkbook();
} else {
return createHSSFWorkbook();
}
}
/**
* Creates a HSSFWorkbook from the given NPOIFSFileSystem<p>
*
@ -296,6 +314,11 @@ public class WorkbookFactory {
return createWorkbook("org.apache.poi.xssf.usermodel.XSSFWorkbookFactory", args);
}
/**
* Does the actual call to HSSF or XSSF to do the creation.
* Uses reflection, so that this class can be in the Core non-OOXML
* POI jar without errors / broken references to the OOXML / XSSF code.
*/
private static Workbook createWorkbook(String factoryClass, Object args[]) throws IOException, EncryptedDocumentException {
try {
Class<?> clazz = WorkbookFactory.class.getClassLoader().loadClass(factoryClass);
@ -307,6 +330,8 @@ public class WorkbookFactory {
c = boolean.class;
} else if (InputStream.class.isAssignableFrom(c)) {
c = InputStream.class;
} else if (File.class.isAssignableFrom(c)) {
c = File.class;
}
argsClz[i++] = c;
}

View File

@ -132,7 +132,7 @@ public class CellReference {
if (rowRef.length() == 0) {
_rowIndex = -1;
} else {
// throws NumberFormatException if rowRef is not convertable to an int
// throws NumberFormatException if rowRef is not convertible to an int
_rowIndex = Integer.parseInt(rowRef)-1; // -1 to convert 1-based to zero-based
}
}
@ -336,10 +336,10 @@ public class CellReference {
if(colStr.toUpperCase(Locale.ROOT).compareTo(lastCol) > 0) {
return false;
}
} else {
} /*else {
// apparent column name has less chars than max
// no need to check range
}
}*/
return true;
}
@ -426,7 +426,7 @@ public class CellReference {
// AreaReference.separateAreaRefs()
// SheetNameFormatter.format() (inverse)
StringBuffer sb = new StringBuffer(indexOfSheetNameDelimiter);
StringBuilder sb = new StringBuilder(indexOfSheetNameDelimiter);
for(int i=1; i<lastQuotePos; i++) { // Note boundaries - skip outer quotes
char ch = reference.charAt(i);
@ -495,11 +495,7 @@ public class CellReference {
@Override
public String toString() {
StringBuffer sb = new StringBuffer(64);
sb.append(getClass().getName()).append(" [");
sb.append(formatAsString());
sb.append("]");
return sb.toString();
return getClass().getName() + " [" + formatAsString() + "]";
}
/**

View File

@ -420,7 +420,7 @@ public final class CellUtil {
}
/**
* Utility method that returns the named short value form the given map.
* Utility method that returns the named short value from the given map.
*
* @param properties map of named properties (String -> Object)
* @param name property name
@ -436,7 +436,7 @@ public final class CellUtil {
}
/**
* Utility method that returns the named int value form the given map.
* Utility method that returns the named int value from the given map.
*
* @param properties map of named properties (String -> Object)
* @param name property name
@ -452,7 +452,7 @@ public final class CellUtil {
}
/**
* Utility method that returns the named BorderStyle value form the given map.
* Utility method that returns the named BorderStyle value from the given map.
*
* @param properties map of named properties (String -> Object)
* @param name property name
@ -483,7 +483,7 @@ public final class CellUtil {
}
/**
* Utility method that returns the named FillPatternType value form the given map.
* Utility method that returns the named FillPatternType value from the given map.
*
* @param properties map of named properties (String -> Object)
* @param name property name
@ -515,7 +515,7 @@ public final class CellUtil {
}
/**
* Utility method that returns the named HorizontalAlignment value form the given map.
* Utility method that returns the named HorizontalAlignment value from the given map.
*
* @param properties map of named properties (String -> Object)
* @param name property name
@ -547,7 +547,7 @@ public final class CellUtil {
}
/**
* Utility method that returns the named VerticalAlignment value form the given map.
* Utility method that returns the named VerticalAlignment value from the given map.
*
* @param properties map of named properties (String -> Object)
* @param name property name
@ -579,7 +579,7 @@ public final class CellUtil {
}
/**
* Utility method that returns the named boolean value form the given map.
* Utility method that returns the named boolean value from the given map.
*
* @param properties map of properties (String -> Object)
* @param name property name
@ -594,7 +594,7 @@ public final class CellUtil {
}
return false;
}
/**
* Utility method that puts the given value to the given map.
*

View File

@ -571,6 +571,22 @@ public final class IOUtils {
return new byte[(int)length];
}
/**
* Simple utility function to check that you haven't hit EOF
* when reading a byte.
*
* @param is inputstream to read
* @return byte read, unless
* @throws IOException on IOException or EOF if -1 is read
*/
public static int readByte(InputStream is) throws IOException {
int b = is.read();
if (b == -1) {
throw new EOFException();
}
return b;
}
private static void throwRFE(long length, int maxLength) {
throw new RecordFormatException("Tried to allocate an array of length "+length +
", but "+ maxLength+" is the maximum for this record type.\n" +

View File

@ -42,6 +42,7 @@ import org.apache.poi.util.POILogger;
import org.apache.poi.xddf.usermodel.chart.XDDFChart;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFRelation;
/**
* Represents an entry of a OOXML package.
@ -613,6 +614,14 @@ public class POIXMLDocumentPart {
*/
protected void read(POIXMLFactory factory, Map<PackagePart, POIXMLDocumentPart> context) throws OpenXML4JException {
PackagePart pp = getPackagePart();
if (pp.getContentType().equals(XWPFRelation.TEMPLATE.getContentType())) {
logger.log(POILogger.WARN,
"POI does not currently support template.main+xml (glossary) parts. " +
"Skipping this part for now.");
return;
}
// add mapping a second time, in case of initial caller hasn't done so
POIXMLDocumentPart otherChild = context.put(pp, this);
if (otherChild != null && otherChild != this) {

View File

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

View File

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

View File

@ -63,7 +63,7 @@ import org.w3c.dom.events.EventListener;
* This class bundles the configuration options used for the existing
* signature facets.
* Apart of the thread local members (e.g. opc-package) most values will probably be constant, so
* it might be configured centrally (e.g. by spring)
* it might be configured centrally (e.g. by spring)
*/
@SuppressWarnings({"unused","WeakerAccess"})
public class SignatureConfig {
@ -76,14 +76,14 @@ public class SignatureConfig {
public interface SignatureConfigurable {
void setSignatureConfig(SignatureConfig signatureConfig);
void setSignatureConfig(SignatureConfig signatureConfig);
}
private ThreadLocal<OPCPackage> opcPackage = new ThreadLocal<>();
private ThreadLocal<XMLSignatureFactory> signatureFactory = new ThreadLocal<>();
private ThreadLocal<KeyInfoFactory> keyInfoFactory = new ThreadLocal<>();
private ThreadLocal<Provider> provider = new ThreadLocal<>();
private List<SignatureFacet> signatureFacets = new ArrayList<>();
private HashAlgorithm digestAlgo = HashAlgorithm.sha256;
private Date executionTime = new Date();
@ -96,11 +96,11 @@ public class SignatureConfig {
private SignaturePolicyService signaturePolicyService;
private URIDereferencer uriDereferencer;
private String canonicalizationMethod = CanonicalizationMethod.INCLUSIVE;
private boolean includeEntireCertificateChain = true;
private boolean includeIssuerSerial;
private boolean includeKeyValue;
/**
* the time-stamp service used for XAdES-T and XAdES-X.
*/
@ -123,7 +123,7 @@ public class SignatureConfig {
private String tspRequestPolicy = "1.3.6.1.4.1.13762.3";
private String userAgent = "POI XmlSign Service TSP Client";
private String proxyUrl;
/**
* the optional revocation data service used for XAdES-C and XAdES-X-L.
* When <code>null</code> the signature will be limited to XAdES-T only.
@ -148,16 +148,16 @@ public class SignatureConfig {
* <code>null</code> value will trigger an automatically generated signature Id.
*/
private String packageSignatureId = "idPackageSignature";
/**
* Gives back the human-readable description of what the citizen will be
* signing. The default value is "Office OpenXML Document".
*/
private String signatureDescription = "Office OpenXML Document";
/**
* The process of signing includes the marshalling of xml structures.
* This also includes the canonicalization. Currently this leads to problems
* This also includes the canonicalization. Currently this leads to problems
* with certain namespaces, so this EventListener is used to interfere
* with the marshalling process.
*/
@ -177,7 +177,7 @@ public class SignatureConfig {
/**
* Inits and checks the config object.
* If not set previously, complex configuration properties also get
* If not set previously, complex configuration properties also get
* created/initialized via this initialization call.
*
* @param onlyValidation if true, only a subset of the properties
@ -202,7 +202,7 @@ public class SignatureConfig {
namespacePrefixes.put(OO_DIGSIG_NS, "mdssi");
namespacePrefixes.put(XADES_132_NS, "xd");
}
if (onlyValidation) {
return;
}
@ -210,15 +210,15 @@ public class SignatureConfig {
if (signatureMarshalListener == null) {
signatureMarshalListener = new SignatureMarshalListener();
}
if (signatureMarshalListener instanceof SignatureConfigurable) {
((SignatureConfigurable)signatureMarshalListener).setSignatureConfig(this);
}
if (tspService != null) {
tspService.setSignatureConfig(this);
}
if (signatureFacets.isEmpty()) {
addSignatureFacet(new OOXMLSignatureFacet());
addSignatureFacet(new KeyInfoSignatureFacet());
@ -230,14 +230,14 @@ public class SignatureConfig {
sf.setSignatureConfig(this);
}
}
/**
* @param signatureFacet the signature facet is appended to facet list
* @param signatureFacet the signature facet is appended to facet list
*/
public void addSignatureFacet(SignatureFacet signatureFacet) {
signatureFacets.add(signatureFacet);
}
/**
* @return the list of facets, may be empty when the config object is not initialized
*/
@ -265,14 +265,14 @@ public class SignatureConfig {
public void setDigestAlgo(HashAlgorithm digestAlgo) {
this.digestAlgo = digestAlgo;
}
/**
* @return the opc package to be used by this thread, stored as thread-local
*/
public OPCPackage getOpcPackage() {
return opcPackage.get();
}
/**
* @param opcPackage the opc package to be handled by this thread, stored as thread-local
*/
@ -398,14 +398,14 @@ public class SignatureConfig {
public void setSignatureDescription(String signatureDescription) {
this.signatureDescription = signatureDescription;
}
/**
* @return the default canonicalization method, defaults to INCLUSIVE
*/
public String getCanonicalizationMethod() {
return canonicalizationMethod;
}
/**
* @param canonicalizationMethod the default canonicalization method
*/
@ -459,15 +459,15 @@ public class SignatureConfig {
public void setTspUrl(String tspUrl) {
this.tspUrl = tspUrl;
}
/**
* @return if true, uses timestamp-request/response mimetype,
* if false, timestamp-query/reply mimetype
* if false, timestamp-query/reply mimetype
*/
public boolean isTspOldProtocol() {
return tspOldProtocol;
}
/**
* @param tspOldProtocol defines the timestamp-protocol mimetype
* @see #isTspOldProtocol
@ -475,7 +475,7 @@ public class SignatureConfig {
public void setTspOldProtocol(boolean tspOldProtocol) {
this.tspOldProtocol = tspOldProtocol;
}
/**
* @return the hash algorithm to be used for the timestamp entry.
* Defaults to the hash algorithm of the main entry
@ -483,7 +483,7 @@ public class SignatureConfig {
public HashAlgorithm getTspDigestAlgo() {
return nvl(tspDigestAlgo,digestAlgo);
}
/**
* @param tspDigestAlgo the algorithm to be used for the timestamp entry.
* if <code>null</code>, the hash algorithm of the main entry
@ -499,7 +499,7 @@ public class SignatureConfig {
public String getProxyUrl() {
return proxyUrl;
}
/**
* @param proxyUrl the proxy url to be used for all communications.
* Currently this affects the timestamp service
@ -507,56 +507,56 @@ public class SignatureConfig {
public void setProxyUrl(String proxyUrl) {
this.proxyUrl = proxyUrl;
}
/**
* @return the timestamp service. Defaults to {@link TSPTimeStampService}
*/
public TimeStampService getTspService() {
return tspService;
}
/**
* @param tspService the timestamp service
*/
public void setTspService(TimeStampService tspService) {
this.tspService = tspService;
}
/**
* @return the user id for the timestamp service - currently only basic authorization is supported
*/
public String getTspUser() {
return tspUser;
}
/**
* @param tspUser the user id for the timestamp service - currently only basic authorization is supported
*/
public void setTspUser(String tspUser) {
this.tspUser = tspUser;
}
/**
* @return the password for the timestamp service
*/
public String getTspPass() {
return tspPass;
}
/**
* @param tspPass the password for the timestamp service
*/
public void setTspPass(String tspPass) {
this.tspPass = tspPass;
}
/**
* @return the validator for the timestamp service (certificate)
*/
public TimeStampServiceValidator getTspValidator() {
return tspValidator;
}
/**
* @param tspValidator the validator for the timestamp service (certificate)
*/
@ -586,7 +586,7 @@ public class SignatureConfig {
public HashAlgorithm getXadesDigestAlgo() {
return nvl(xadesDigestAlgo,digestAlgo);
}
/**
* @param xadesDigestAlgo hash algorithm used for XAdES.
* When <code>null</code>, defaults to {@link #getDigestAlgo()}
@ -611,7 +611,7 @@ public class SignatureConfig {
public String getUserAgent() {
return userAgent;
}
/**
* @param userAgent the user agent used for http communication (e.g. to the TSP)
*/
@ -626,7 +626,7 @@ public class SignatureConfig {
public String getTspRequestPolicy() {
return tspRequestPolicy;
}
/**
* @param tspRequestPolicy the asn.1 object id for the tsp request policy.
*/
@ -636,7 +636,7 @@ public class SignatureConfig {
/**
* @return true, if the whole certificate chain is included in the signature.
* When false, only the signer cert will be included
* When false, only the signer cert will be included
*/
public boolean isIncludeEntireCertificateChain() {
return includeEntireCertificateChain;
@ -728,7 +728,7 @@ public class SignatureConfig {
* Make sure the DN is encoded using the same order as present
* within the certificate. This is an Office2010 work-around.
* Should be reverted back.
*
*
* XXX: not correct according to RFC 4514.
*
* @return when true, the issuer DN is used instead of the issuer X500 principal
@ -744,7 +744,7 @@ public class SignatureConfig {
this.xadesIssuerNameNoReverseOrder = xadesIssuerNameNoReverseOrder;
}
/**
* @return the event listener which is active while xml structure for
* the signature is created.
@ -813,8 +813,8 @@ public class SignatureConfig {
/**
* Converts the digest algorithm - currently only sha* and ripemd160 is supported.
* MS Office only supports sha1, sha256, sha384, sha512.
*
* MS Office only supports sha1, sha256, sha384, sha512.
*
* @param digestAlgo the digest algorithm
* @return the uri for the given digest
*/
@ -835,7 +835,7 @@ public class SignatureConfig {
* Converts the digest algorithm ur - currently only sha* and ripemd160 is supported.
* MS Office only supports sha1, sha256, sha384, sha512.
*
* @param digestAlgo the digest algorithm uri
* @param digestMethodUri the digest algorithm uri
* @return the hash algorithm for the given digest
*/
private static HashAlgorithm getDigestMethodAlgo(String digestMethodUri) {
@ -895,7 +895,7 @@ public class SignatureConfig {
public void setSignatureFactory(XMLSignatureFactory signatureFactory) {
this.signatureFactory.set(signatureFactory);
}
/**
* @return the xml signature factory (thread-local)
*/
@ -914,7 +914,7 @@ public class SignatureConfig {
public void setKeyInfoFactory(KeyInfoFactory keyInfoFactory) {
this.keyInfoFactory.set(keyInfoFactory);
}
/**
* @return the key factory (thread-local)
*/
@ -934,10 +934,10 @@ public class SignatureConfig {
* <li>the Santuario xmlsec provider</li>
* <li>the JDK xmlsec provider</li>
* </ul>
*
*
* For signing the classes are linked against the Santuario xmlsec, so this might
* only work for validation (not tested).
*
*
* @return the xml dsig provider
*/
public Provider getProvider() {
@ -948,7 +948,7 @@ public class SignatureConfig {
// Santuario xmlsec
"org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI",
// JDK xmlsec
"org.jcp.xml.dsig.internal.dom.XMLDSigRI"
"org.jcp.xml.dsig.internal.dom.XMLDSigRI"
};
for (String pn : dsigProviderNames) {
if (pn == null) {
@ -966,7 +966,7 @@ public class SignatureConfig {
if (prov == null) {
throw new RuntimeException("JRE doesn't support default xml signature provider - set jsr105Provider system property!");
}
return prov;
}

View File

@ -116,13 +116,15 @@ public class XDGFShape extends XDGFSheet {
_parentPage = parentPage;
TextType text = shapeSheet.getText();
if (text != null)
if (text != null) {
_text = new XDGFText(text, this);
}
if (shapeSheet.isSetShapes()) {
_shapes = new ArrayList<>();
for (ShapeSheetType shape : shapeSheet.getShapes().getShapeArray())
for (ShapeSheetType shape : shapeSheet.getShapes().getShapeArray()) {
_shapes.add(new XDGFShape(this, shape, parentPage, document));
}
}
readProperties();
@ -130,10 +132,11 @@ public class XDGFShape extends XDGFSheet {
@Override
public String toString() {
if (_parentPage instanceof XDGFMasterContents)
if (_parentPage instanceof XDGFMasterContents) {
return _parentPage + ": <Shape ID=\"" + getID() + "\">";
else
} else {
return "<Shape ID=\"" + getID() + "\">";
}
}
protected void readProperties() {
@ -181,9 +184,10 @@ public class XDGFShape extends XDGFSheet {
if (obj.isSetMaster()) {
_master = pageContents.getMasterById(obj.getMaster());
if (_master == null)
if (_master == null) {
throw XDGFException.error("refers to non-existant master "
+ obj.getMaster(), this);
}
/*
* If a master has one top-level shape, a shape that inherits from
@ -209,11 +213,12 @@ public class XDGFShape extends XDGFSheet {
}
} else if (obj.isSetMasterShape()) {
_masterShape = master.getShapeById(obj.getMasterShape());
if (_masterShape == null)
_masterShape = (master == null) ? null : master.getShapeById(obj.getMasterShape());
if (_masterShape == null) {
throw XDGFException.error(
"refers to non-existant master shape "
+ obj.getMasterShape(), this);
}
}
@ -229,21 +234,24 @@ public class XDGFShape extends XDGFSheet {
protected void setupSectionMasters() {
if (_masterShape == null)
if (_masterShape == null) {
return;
}
try {
for (Entry<String, XDGFSection> section : _sections.entrySet()) {
XDGFSection master = _masterShape.getSection(section.getKey());
if (master != null)
if (master != null) {
section.getValue().setupMaster(master);
}
}
for (Entry<Long, GeometrySection> section : _geometry.entrySet()) {
GeometrySection master = _masterShape.getGeometryByIdx(section
.getKey());
if (master != null)
if (master != null) {
section.getValue().setupMaster(master);
}
}
} catch (POIXMLException e) {
throw XDGFException.wrap(this.toString(), e);
@ -266,8 +274,9 @@ public class XDGFShape extends XDGFSheet {
public String getTextAsString() {
XDGFText text = getText();
if (text == null)
if (text == null) {
return "";
}
return text.getTextContent();
}
@ -294,7 +303,7 @@ public class XDGFShape extends XDGFSheet {
}
/**
* Only available if this shape is a shape group, may be null
* Only available if this shape is a shape group, may be null
*/
// -> May be null
public List<XDGFShape> getShapes() {
@ -304,28 +313,32 @@ public class XDGFShape extends XDGFSheet {
// unique to this shape on the page?
public String getName() {
String name = getXmlObject().getName();
if (name == null)
if (name == null) {
return "";
}
return name;
}
// unique to this shape on the page?
public String getShapeType() {
String type = getXmlObject().getType();
if (type == null)
if (type == null) {
return "";
}
return type;
}
// name of the symbol that this was derived from
public String getSymbolName() {
if (_master == null)
if (_master == null) {
return "";
}
String name = _master.getName();
if (name == null)
if (name == null) {
return "";
}
return name;
}
@ -345,8 +358,9 @@ public class XDGFShape extends XDGFSheet {
XDGFShape top = null;
if (_parent != null) {
top = _parent.getTopmostParentShape();
if (top == null)
if (top == null) {
top = _parent;
}
}
return top;
@ -381,190 +395,223 @@ public class XDGFShape extends XDGFSheet {
}
public XDGFText getText() {
if (_text == null && _masterShape != null)
if (_text == null && _masterShape != null) {
return _masterShape.getText();
}
return _text;
}
public Double getPinX() {
if (_pinX == null && _masterShape != null)
if (_pinX == null && _masterShape != null) {
return _masterShape.getPinX();
}
if (_pinX == null)
if (_pinX == null) {
throw XDGFException.error("PinX not set!", this);
}
return _pinX;
}
public Double getPinY() {
if (_pinY == null && _masterShape != null)
if (_pinY == null && _masterShape != null) {
return _masterShape.getPinY();
}
if (_pinY == null)
if (_pinY == null) {
throw XDGFException.error("PinY not specified!", this);
}
return _pinY;
}
public Double getWidth() {
if (_width == null && _masterShape != null)
if (_width == null && _masterShape != null) {
return _masterShape.getWidth();
}
if (_width == null)
if (_width == null) {
throw XDGFException.error("Width not specified!", this);
}
return _width;
}
public Double getHeight() {
if (_height == null && _masterShape != null)
if (_height == null && _masterShape != null) {
return _masterShape.getHeight();
}
if (_height == null)
if (_height == null) {
throw XDGFException.error("Height not specified!", this);
}
return _height;
}
public Double getLocPinX() {
if (_locPinX == null && _masterShape != null)
if (_locPinX == null && _masterShape != null) {
return _masterShape.getLocPinX();
}
if (_locPinX == null)
if (_locPinX == null) {
throw XDGFException.error("LocPinX not specified!", this);
}
return _locPinX;
}
public Double getLocPinY() {
if (_locPinY == null && _masterShape != null)
if (_locPinY == null && _masterShape != null) {
return _masterShape.getLocPinY();
}
if (_locPinY == null)
if (_locPinY == null) {
throw XDGFException.error("LocPinY not specified!", this);
}
return _locPinY;
}
public Double getBeginX() {
if (_beginX == null && _masterShape != null)
if (_beginX == null && _masterShape != null) {
return _masterShape.getBeginX();
}
return _beginX;
}
public Double getBeginY() {
if (_beginY == null && _masterShape != null)
if (_beginY == null && _masterShape != null) {
return _masterShape.getBeginY();
}
return _beginY;
}
public Double getEndX() {
if (_endX == null && _masterShape != null)
if (_endX == null && _masterShape != null) {
return _masterShape.getEndX();
}
return _endX;
}
public Double getEndY() {
if (_endY == null && _masterShape != null)
if (_endY == null && _masterShape != null) {
return _masterShape.getEndY();
}
return _endY;
}
public Double getAngle() {
if (_angle == null && _masterShape != null)
if (_angle == null && _masterShape != null) {
return _masterShape.getAngle();
}
return _angle;
}
public Boolean getFlipX() {
if (_flipX == null && _masterShape != null)
if (_flipX == null && _masterShape != null) {
return _masterShape.getFlipX();
}
return _flipX;
}
public Boolean getFlipY() {
if (_flipY == null && _masterShape != null)
if (_flipY == null && _masterShape != null) {
return _masterShape.getFlipY();
}
return _flipY;
}
public Double getTxtPinX() {
if (_txtPinX == null && _masterShape != null
&& _masterShape._txtPinX != null)
&& _masterShape._txtPinX != null) {
return _masterShape._txtPinX;
}
if (_txtPinX == null)
if (_txtPinX == null) {
return getWidth() * 0.5;
}
return _txtPinX;
}
public Double getTxtPinY() {
if (_txtLocPinY == null && _masterShape != null
&& _masterShape._txtLocPinY != null)
&& _masterShape._txtLocPinY != null) {
return _masterShape._txtLocPinY;
}
if (_txtPinY == null)
if (_txtPinY == null) {
return getHeight() * 0.5;
}
return _txtPinY;
}
public Double getTxtLocPinX() {
if (_txtLocPinX == null && _masterShape != null
&& _masterShape._txtLocPinX != null)
&& _masterShape._txtLocPinX != null) {
return _masterShape._txtLocPinX;
}
if (_txtLocPinX == null)
if (_txtLocPinX == null) {
return getTxtWidth() * 0.5;
}
return _txtLocPinX;
}
public Double getTxtLocPinY() {
if (_txtLocPinY == null && _masterShape != null
&& _masterShape._txtLocPinY != null)
&& _masterShape._txtLocPinY != null) {
return _masterShape._txtLocPinY;
}
if (_txtLocPinY == null)
if (_txtLocPinY == null) {
return getTxtHeight() * 0.5;
}
return _txtLocPinY;
}
public Double getTxtAngle() {
if (_txtAngle == null && _masterShape != null)
if (_txtAngle == null && _masterShape != null) {
return _masterShape.getTxtAngle();
}
return _txtAngle;
}
public Double getTxtWidth() {
if (_txtWidth == null && _masterShape != null
&& _masterShape._txtWidth != null)
&& _masterShape._txtWidth != null) {
return _masterShape._txtWidth;
}
if (_txtWidth == null)
if (_txtWidth == null) {
return getWidth();
}
return _txtWidth;
}
public Double getTxtHeight() {
if (_txtHeight == null && _masterShape != null
&& _masterShape._txtHeight != null)
&& _masterShape._txtHeight != null) {
return _masterShape._txtHeight;
}
if (_txtHeight == null)
if (_txtHeight == null) {
return getHeight();
}
return _txtHeight;
}
@ -573,8 +620,9 @@ public class XDGFShape extends XDGFSheet {
public Integer getLineCap() {
Integer lineCap = super.getLineCap();
if (lineCap != null)
if (lineCap != null) {
return lineCap;
}
// get from master
if (_masterShape != null) {
@ -589,8 +637,9 @@ public class XDGFShape extends XDGFSheet {
public Color getLineColor() {
Color lineColor = super.getLineColor();
if (lineColor != null)
if (lineColor != null) {
return lineColor;
}
// get from master
if (_masterShape != null) {
@ -605,8 +654,9 @@ public class XDGFShape extends XDGFSheet {
public Integer getLinePattern() {
Integer linePattern = super.getLinePattern();
if (linePattern != null)
if (linePattern != null) {
return linePattern;
}
// get from master
if (_masterShape != null) {
@ -621,8 +671,9 @@ public class XDGFShape extends XDGFSheet {
public Double getLineWeight() {
Double lineWeight = super.getLineWeight();
if (lineWeight != null)
if (lineWeight != null) {
return lineWeight;
}
// get from master
if (_masterShape != null) {
@ -637,8 +688,9 @@ public class XDGFShape extends XDGFSheet {
public Color getFontColor() {
Color fontColor = super.getFontColor();
if (fontColor != null)
if (fontColor != null) {
return fontColor;
}
// get from master
if (_masterShape != null) {
@ -653,8 +705,9 @@ public class XDGFShape extends XDGFSheet {
public Double getFontSize() {
Double fontSize = super.getFontSize();
if (fontSize != null)
if (fontSize != null) {
return fontSize;
}
// get from master
if (_masterShape != null) {
@ -791,11 +844,11 @@ public class XDGFShape extends XDGFSheet {
public Rectangle2D.Double getBounds() {
return new Rectangle2D.Double(0, 0, getWidth(), getHeight());
}
/**
* @return returns bounds as a path in local coordinates, which is
* userful if you need to transform to global coordinates
*
*
* Warning: Don't use this for 1d objects, and will fail for
* infinite line objects
*/
@ -819,8 +872,9 @@ public class XDGFShape extends XDGFSheet {
*/
public Path2D.Double getPath() {
for (GeometrySection geoSection : getGeometrySections()) {
if (geoSection.getNoShow())
if (geoSection.getNoShow()) {
continue;
}
return geoSection.getPath(this);
}
@ -833,8 +887,9 @@ public class XDGFShape extends XDGFSheet {
*/
public boolean hasGeometry() {
for (GeometrySection geoSection : getGeometrySections()) {
if (!geoSection.getNoShow())
if (!geoSection.getNoShow()) {
return true;
}
}
return false;
}
@ -889,8 +944,9 @@ public class XDGFShape extends XDGFSheet {
tr.concatenate(getParentTransform());
try {
if (visitor.accept(this))
if (visitor.accept(this)) {
visitor.visit(this, tr, level);
}
if (_shapes != null) {
for (XDGFShape shape : _shapes) {
@ -914,8 +970,9 @@ public class XDGFShape extends XDGFSheet {
public void visitShapes(ShapeVisitor visitor, int level) {
try {
if (visitor.accept(this))
if (visitor.accept(this)) {
visitor.visit(this, null, level);
}
if (_shapes != null) {
for (XDGFShape shape : _shapes) {

View File

@ -52,7 +52,7 @@ public class XDGFText {
// is a mixed type)
return ((TextTypeImpl) _text).getStringValue();
}
/**
* These are in the shape coordinate system
*
@ -82,8 +82,8 @@ public class XDGFText {
public Path2D.Double getBoundsAsPath() {
Rectangle2D.Double rect = getTextBounds();
Double w = rect.getWidth();
Double h = rect.getHeight();
double w = rect.getWidth();
double h = rect.getHeight();
Path2D.Double bounds = new Path2D.Double();
bounds.moveTo(0, 0);
@ -94,7 +94,7 @@ public class XDGFText {
return bounds;
}
/**
* @return Center of text in local coordinates
*/
@ -110,8 +110,9 @@ public class XDGFText {
public void draw(Graphics2D graphics) {
String textContent = getTextContent();
if (textContent.length() == 0)
if (textContent.length() == 0) {
return;
}
Rectangle2D.Double bounds = getTextBounds();
@ -140,22 +141,25 @@ public class XDGFText {
}
Double txtAngle = _parent.getTxtAngle();
if (txtAngle != null && Math.abs(txtAngle) > 0.01)
if (txtAngle != null && Math.abs(txtAngle) > 0.01) {
graphics.rotate(txtAngle);
}
float nextY = 0;
for (String line : lines) {
if (line.length() == 0)
if (line.length() == 0) {
continue;
}
TextLayout layout = new TextLayout(line, font, frc);
if (layout.isLeftToRight())
if (layout.isLeftToRight()) {
layout.draw(graphics, 0, nextY);
else
} else {
layout.draw(graphics,
(float) (bounds.width - layout.getAdvance()), nextY);
}
nextY += layout.getAscent() + layout.getDescent()
+ layout.getLeading();

View File

@ -22,6 +22,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
@ -38,17 +39,17 @@ import org.apache.poi.xdgf.usermodel.shape.ShapeVisitor;
public class HierarchyPrinter {
public static void printHierarchy(XDGFPage page, File outDir)
throws FileNotFoundException, UnsupportedEncodingException {
throws FileNotFoundException, UnsupportedEncodingException, IOException {
File pageFile = new File(outDir, "page" + page.getPageNumber() + "-"
+ Util.sanitizeFilename(page.getName()) + ".txt");
OutputStream os = new FileOutputStream(pageFile);
PrintStream pos = new PrintStream(os, false, "utf-8");
printHierarchy(page, pos);
pos.close();
try (
OutputStream os = new FileOutputStream(pageFile);
PrintStream pos = new PrintStream(os, false, "utf-8")
) {
printHierarchy(page, pos);
}
}
public static void printHierarchy(XDGFPage page, final PrintStream os) {
@ -71,7 +72,7 @@ public class HierarchyPrinter {
}
public static void printHierarchy(XmlVisioDocument document,
String outDirname) throws FileNotFoundException, UnsupportedEncodingException {
String outDirname) throws FileNotFoundException, UnsupportedEncodingException, IOException {
File outDir = new File(outDirname);
@ -89,8 +90,9 @@ public class HierarchyPrinter {
String inFilename = args[0];
String outDir = args[1];
XmlVisioDocument doc = new XmlVisioDocument(new FileInputStream(
inFilename));
printHierarchy(doc, outDir);
try (FileInputStream is = new FileInputStream(inFilename)) {
XmlVisioDocument doc = new XmlVisioDocument(is);
printHierarchy(doc, outDir);
}
}
}

View File

@ -21,7 +21,10 @@ import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
@ -33,7 +36,7 @@ import org.apache.poi.xdgf.usermodel.shape.ShapeRenderer;
/**
* Converts a Visio diagram to a PNG file.
*
*
* As more elements and styles are added/supported the output will get
* better, but it's very rough right now.
*/
@ -91,11 +94,8 @@ public class VsdxToPng {
graphics.dispose();
OutputStream out = new FileOutputStream(outFile);
try {
try (FileOutputStream out = new FileOutputStream(outFile)) {
ImageIO.write(img, "png", out);
} finally {
out.close();
}
}
@ -127,8 +127,9 @@ public class VsdxToPng {
renderer = new ShapeDebuggerRenderer();
}
XmlVisioDocument doc = new XmlVisioDocument(new FileInputStream(
inFilename));
renderToPng(doc, pngDir, 2000 / 11.0, renderer);
try (FileInputStream is = new FileInputStream(inFilename)) {
XmlVisioDocument doc = new XmlVisioDocument(is);
renderToPng(doc, pngDir, 2000 / 11.0, renderer);
}
}
}

View File

@ -36,6 +36,7 @@ import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.extractor.POIXMLPropertiesTextExtractor;
import org.apache.poi.ooxml.util.PackageHelper;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
@ -50,7 +51,6 @@ import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.ooxml.util.PackageHelper;
import org.apache.poi.util.Units;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
@ -362,7 +362,7 @@ public class XMLSlideShow extends POIXMLDocument
CTNotesMasterIdListEntry notesMasterId = notesMasterIdList.addNewNotesMasterId();
notesMasterId.setId(rp.getRelationship().getId());
Integer themeIndex = 1;
int themeIndex = 1;
// TODO: check if that list can be replaced by idx = Math.max(idx,themeIdx)
List<Integer> themeIndexList = new ArrayList<>();
for (POIXMLDocumentPart p : getRelations()) {
@ -626,7 +626,7 @@ public class XMLSlideShow extends POIXMLDocument
// TODO: implement!
throw new UnsupportedOperationException();
}
@Override
public POIXMLPropertiesTextExtractor getMetadataTextExtractor() {
return new POIXMLPropertiesTextExtractor(this);

View File

@ -48,7 +48,7 @@ import org.w3c.dom.Node;
@Internal
public class XSLFColor {
private final static POILogger LOGGER = POILogFactory.getLogger(XSLFColor.class);
private XmlObject _xmlObject;
private Color _color;
private CTSchemeColor _phClr;
@ -128,7 +128,7 @@ public class XSLFColor {
}
};
}
private Color toColor(XmlObject obj, XSLFTheme theme) {
Color color = null;
for (XmlObject ch : obj.selectPath("*")) {
@ -207,19 +207,19 @@ public class XSLFColor {
if (fill.isSetScrgbClr()) {
fill.unsetScrgbClr();
}
if (fill.isSetHslClr()) {
fill.unsetHslClr();
}
if (fill.isSetPrstClr()) {
fill.unsetPrstClr();
}
if (fill.isSetSchemeClr()) {
fill.unsetSchemeClr();
}
if (fill.isSetSysClr()) {
fill.unsetSysClr();
}
@ -227,12 +227,12 @@ public class XSLFColor {
float[] rgbaf = color.getRGBComponents(null);
boolean addAlpha = (rgbaf.length == 4 && rgbaf[3] < 1f);
CTPositiveFixedPercentage alphaPct;
// see office open xml part 4 - 5.1.2.2.30 and 5.1.2.2.32
if (isInt(rgbaf[0]) && isInt(rgbaf[1]) && isInt(rgbaf[2])) {
// sRGB has a gamma of 2.2
CTSRgbColor rgb = fill.addNewSrgbClr();
byte rgbBytes[] = { (byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue() };
rgb.setVal(rgbBytes);
alphaPct = (addAlpha) ? rgb.addNewAlpha() : null;
@ -249,14 +249,14 @@ public class XSLFColor {
alphaPct.setVal((int)(100000 * rgbaf[3]));
}
}
/**
* @return true, if this is an integer color value
*/
private static boolean isInt(float f) {
return Math.abs((f*255f) - Math.rint(f*255f)) < 0.00001f;
return Math.abs((f*255d) - Math.rint(f*255d)) < 0.00001;
}
private int getRawValue(String elem) {
String query = "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' $this//a:" + elem;
@ -281,9 +281,9 @@ public class XSLFColor {
}
}
return -1;
return -1;
}
/**
* Read a perecentage value from the supplied xml bean.
* Example:
@ -305,7 +305,7 @@ public class XSLFColor {
* or -1 if the value is not set
*/
int getAlpha(){
return getPercentageValue("alpha");
return getPercentageValue("alpha");
}
/**
@ -413,7 +413,7 @@ public class XSLFColor {
/**
* specifies the input color with the specific red component, but with the blue and green color
* components unchanged
*
*
* @return the value of the red component specified as a
* percentage with 0% indicating minimal blue and 100% indicating maximum
* or -1 if the value is not set
@ -479,7 +479,7 @@ public class XSLFColor {
/**
* specifies a darker version of its input color.
* A 10% shade is 10% of the input color combined with 90% black.
*
*
* @return the value of the shade specified as a
* percentage with 0% indicating minimal shade and 100% indicating maximum
* or -1 if the value is not set

View File

@ -49,9 +49,7 @@ implements Notes<XSLFShape,XSLFTextParagraph> {
*
* @param part the package part holding the notes data,
* the content type must be <code>application/vnd.openxmlformats-officedocument.notes+xml</code>
* @param rel the package relationship holding this notes,
* the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/notes
*
*
* @since POI 3.14-Beta1
*/
XSLFNotes(PackagePart part) throws IOException, XmlException {
@ -77,7 +75,7 @@ implements Notes<XSLFShape,XSLFTextParagraph> {
@Override
protected String getRootElementName(){
return "notes";
return "notes";
}
@Override

View File

@ -70,7 +70,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
@Beta
public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
static final String PML_NS = "http://schemas.openxmlformats.org/presentationml/2006/main";
private final XmlObject _shape;
private final XSLFSheet _sheet;
private XSLFShapeContainer _parent;
@ -82,7 +82,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
_shape = shape;
_sheet = sheet;
}
/**
* @return the xml bean holding this shape's data
*/
@ -91,11 +91,12 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
// the (not existing) xmlbeans hierarchy and subclasses shouldn't narrow it's return value
return _shape;
}
@Override
public XSLFSheet getSheet() {
return _sheet;
}
@Override
public String getShapeName(){
return getCNvPr().getName();
@ -124,22 +125,24 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
PlaceableShape<?,?> ps = (PlaceableShape<?,?>)this;
ps.setAnchor(sh.getAnchor());
}
}
public void setParent(XSLFShapeContainer parent) {
this._parent = parent;
}
@Override
public XSLFShapeContainer getParent() {
return this._parent;
}
protected PaintStyle getFillPaint() {
final XSLFTheme theme = getSheet().getTheme();
final boolean hasPlaceholder = getPlaceholder() != null;
PropertyFetcher<PaintStyle> fetcher = new PropertyFetcher<PaintStyle>() {
@Override
public boolean fetch(XSLFShape shape) {
XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(shape.getShapeProperties());
if (fp == null) {
@ -150,7 +153,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
setValue(null);
return true;
}
PackagePart pp = shape.getSheet().getPackagePart();
PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder);
if (paint != null) {
@ -167,8 +170,8 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
setValue(paint);
return true;
}
return false;
}
};
@ -181,16 +184,16 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
protected CTBackgroundProperties getBgPr() {
return getChild(CTBackgroundProperties.class, PML_NS, "bgPr");
}
@SuppressWarnings("unused")
protected CTStyleMatrixReference getBgRef() {
return getChild(CTStyleMatrixReference.class, PML_NS, "bgRef");
}
protected CTGroupShapeProperties getGrpSpPr() {
return getChild(CTGroupShapeProperties.class, PML_NS, "grpSpPr");
}
protected CTNonVisualDrawingProps getCNvPr() {
if (_nvPr == null) {
String xquery = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr";
@ -239,7 +242,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
public Placeholder getPlaceholder() {
return getPlaceholderDetails().getPlaceholder();
}
/**
* @see PlaceholderDetails#setPlaceholder(Placeholder)
*/
@ -268,7 +271,9 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
@SuppressWarnings({"unchecked", "WeakerAccess"})
protected <T extends XmlObject> T selectProperty(Class<T> resultClass, String xquery) {
XmlObject[] rs = getXmlObject().selectPath(xquery);
if (rs.length == 0) return null;
if (rs.length == 0) {
return null;
}
return (resultClass.isInstance(rs[0])) ? (T)rs[0] : null;
}
@ -281,7 +286,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
* <li>slideLayout
* <li>slideMaster
* </ol>
*
*
* Currently themes and their defaults aren't correctly handled
*
* @param visitor the object that collects the desired property
@ -299,7 +304,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
return false;
}
MasterSheet<XSLFShape,XSLFTextParagraph> sm = getSheet().getMasterSheet();
// try slide layout
if (sm instanceof XSLFSlideLayout) {
XSLFSlideLayout slideLayout = (XSLFSlideLayout)sm;
@ -309,7 +314,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
}
sm = slideLayout.getMasterSheet();
}
// try slide master
if (sm instanceof XSLFSlideMaster) {
XSLFSlideMaster master = (XSLFSlideMaster)sm;
@ -317,15 +322,15 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
XSLFSimpleShape masterShape = master.getPlaceholderByType(textType);
return masterShape != null && visitor.fetch(masterShape);
}
return false;
}
private static int getPlaceholderType(CTPlaceholder ph) {
if ( !ph.isSetType()) {
return STPlaceholderType.INT_BODY;
}
switch (ph.getType().intValue()) {
case STPlaceholderType.INT_TITLE:
case STPlaceholderType.INT_CTR_TITLE:
@ -397,7 +402,8 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
throw new RuntimeException(e);
}
}
@Override
public InputStream getImageData() {
try {
return getPart().getInputStream();
@ -406,17 +412,19 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
}
}
@Override
public String getContentType() {
/* TOOD: map content-type */
return getPart().getContentType();
}
@Override
public int getAlpha() {
return (blip.sizeOfAlphaModFixArray() > 0)
? blip.getAlphaModFixArray(0).getAmt()
: 100000;
}
};
};
}
@SuppressWarnings("WeakerAccess")
@ -426,14 +434,14 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
final CTGradientStop[] gs = gradFill.getGsLst().getGsArray();
Arrays.sort(gs, (o1, o2) -> {
Integer pos1 = o1.getPos();
Integer pos2 = o2.getPos();
return pos1.compareTo(pos2);
int pos1 = o1.getPos();
int pos2 = o2.getPos();
return Integer.compare(pos1, pos2);
});
final ColorStyle cs[] = new ColorStyle[gs.length];
final float fractions[] = new float[gs.length];
int i=0;
for (CTGradientStop cgs : gs) {
CTSchemeColor phClrCgs = phClr;
@ -444,32 +452,37 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
fractions[i] = cgs.getPos() / 100000.f;
i++;
}
return new GradientPaint() {
@Override
public double getGradientAngle() {
return (gradFill.isSetLin())
? gradFill.getLin().getAng() / 60000.d
: 0;
}
@Override
public ColorStyle[] getGradientColors() {
return cs;
}
@Override
public float[] getGradientFractions() {
return fractions;
}
@Override
public boolean isRotatedWithShape() {
return gradFill.getRotWithShape();
}
@Override
public GradientType getGradientType() {
if (gradFill.isSetLin()) {
return GradientType.linear;
}
if (gradFill.isSetPath()) {
/* TODO: handle rect path */
STPathShadeType.Enum ps = gradFill.getPath().getPath();
@ -479,16 +492,18 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
return GradientType.shape;
}
}
return GradientType.linear;
}
};
};
}
@SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) {
if (fillRef == null) return null;
if (fillRef == null) {
return null;
}
// The idx attribute refers to the index of a fill style or
// background fill style within the presentation's style matrix, defined by the fmtScheme element.
// value of 0 or 1000 indicates no background,
@ -513,7 +528,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
fp = XSLFPropertiesDelegate.getFillDelegate(cur.getObject());
}
cur.dispose();
CTSchemeColor phClr = fillRef.getSchemeClr();
PaintStyle res = selectPaint(fp, phClr, theme.getPackagePart(), theme, hasPlaceholder);
// check for empty placeholder value
@ -524,12 +539,12 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
XSLFColor col = new XSLFColor(fillRef, theme, phClr);
return DrawPaint.createSolidPaint(col.getColorStyle());
}
@Override
public void draw(Graphics2D graphics, Rectangle2D bounds) {
DrawFactory.getInstance(graphics).drawShape(graphics, this, bounds);
}
/**
* Return the shape specific (visual) properties
*

View File

@ -74,13 +74,13 @@ public class PPTX2PNG {
for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("-")) {
if ("-scale".equals(args[i])) {
scale = Float.parseFloat(args[++i]);
scale = Float.parseFloat(args[++i]); // lgtm[java/index-out-of-bounds]
} else if ("-slide".equals(args[i])) {
slidenumStr = args[++i];
slidenumStr = args[++i]; // lgtm[java/index-out-of-bounds]
} else if ("-format".equals(args[i])) {
format = args[++i];
format = args[++i]; // lgtm[java/index-out-of-bounds]
} else if ("-outdir".equals(args[i])) {
outdir = new File(args[++i]);
outdir = new File(args[++i]); // lgtm[java/index-out-of-bounds]
} else if ("-quiet".equals(args[i])) {
quiet = true;
}
@ -98,11 +98,11 @@ public class PPTX2PNG {
usage("Invalid format given");
return;
}
if (outdir == null) {
outdir = file.getParentFile();
}
if (!"null".equals(format) && (outdir == null || !outdir.exists() || !outdir.isDirectory())) {
usage("Output directory doesn't exist");
return;
@ -112,7 +112,7 @@ public class PPTX2PNG {
usage("Invalid scale given");
return;
}
if (!quiet) {
System.out.println("Processing " + file);
}
@ -168,7 +168,7 @@ public class PPTX2PNG {
System.out.println("Done");
}
}
private static Set<Integer> slideIndexes(final int slideCount, String range) {
Set<Integer> slideIdx = new TreeSet<>();
if ("-1".equals(range)) {

View File

@ -302,9 +302,8 @@ public class XSSFBSheetHandler extends XSSFBParser {
}
private double rkNumber(byte[] data, int offset) {
//see 2.5.122 for this abomination
//see 2.5.122
byte b0 = data[offset];
String s = Integer.toString(b0, 2);
boolean numDivBy100 = ((b0 & 1) == 1); // else as is
boolean floatingPoint = ((b0 >> 1 & 1) == 0); // else signed integer
@ -320,7 +319,8 @@ public class XSSFBSheetHandler extends XSSFBParser {
if (floatingPoint) {
d = LittleEndian.getDouble(rkBuffer);
} else {
d = LittleEndian.getInt(rkBuffer);
int rawInt = LittleEndian.getInt(rkBuffer, 4);
d = rawInt >> 2;//divide by 4/shift bits coz 30 bit int, not 32
}
d = (numDivBy100) ? d/100 : d;
return d;

View File

@ -51,7 +51,7 @@ public class XSSFBUtils {
int numBytes = 2*(int)numChars;
offset += 4;
if (offset+numBytes > data.length) {
throw new XSSFBParseException("trying to read beyond data length:" +
throw new XSSFBParseException("trying to read beyond data length: " +
"offset="+offset+", numBytes="+numBytes+", data.length="+data.length);
}
sb.append(new String(data, offset, numBytes, StandardCharsets.UTF_16LE));

View File

@ -39,22 +39,22 @@ import org.apache.poi.util.NotImplemented;
public class SXSSFRow implements Row, Comparable<SXSSFRow>
{
private static final Boolean UNDEFINED = null;
private final SXSSFSheet _sheet; // parent sheet
private final SortedMap<Integer, SXSSFCell> _cells = new TreeMap<>();
private short _style = -1; // index of cell style in style table
private short _height = -1; // row height in twips (1/20 point)
private boolean _zHeight; // row zero-height (this is somehow different than being hidden)
private int _outlineLevel; // Outlining level of the row, when outlining is on
// use Boolean to have a tri-state for on/off/undefined
// use Boolean to have a tri-state for on/off/undefined
private Boolean _hidden = UNDEFINED;
private Boolean _collapsed = UNDEFINED;
public SXSSFRow(SXSSFSheet sheet)
{
_sheet=sheet;
}
public Iterator<Cell> allCellsIterator()
{
return new CellIterator();
@ -71,7 +71,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
void setOutlineLevel(int level){
_outlineLevel = level;
}
/**
* get row hidden state: Hidden (true), Unhidden (false), Undefined (null)
*
@ -235,7 +235,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
public SXSSFCell getCell(int cellnum, MissingCellPolicy policy)
{
checkBounds(cellnum);
final SXSSFCell cell = _cells.get(cellnum);
switch (policy) {
case RETURN_NULL_AND_BLANK:
@ -345,10 +345,11 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
@Override
public void setHeightInPoints(float height)
{
if(height==-1)
if(height==-1) {
_height=-1;
else
} else {
_height=(short)(height*20);
}
}
/**
@ -375,7 +376,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
{
return (float)(_height==-1?getSheet().getDefaultRowHeightInPoints():_height/20.0);
}
/**
* Is this row formatted? Most aren't, but some rows
* do have whole-row styles. For those that do, you
@ -392,16 +393,18 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
*/
@Override
public CellStyle getRowStyle() {
if(!isFormatted()) return null;
if(!isFormatted()) {
return null;
}
return getSheet().getWorkbook().getCellStyleAt(_style);
}
@Internal
/*package*/ int getRowStyleIndex() {
return _style;
}
/**
* Applies a whole-row cell styling to the row.
* The row style can be cleared by passing in <code>null</code>.
@ -440,7 +443,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
/**
* Create an iterator over the cells from [0, getLastCellNum()).
* Includes blank cells, excludes empty cells
*
*
* Returns an iterator over all filled cells (created via Row.createCell())
* Throws ConcurrentModificationException if cells are added, moved, or
* removed after the iterator is created.
@ -485,10 +488,11 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
@Override
public Cell next() throws NoSuchElementException
{
if (hasNext())
if (hasNext()) {
return _cells.get(pos++);
else
} else {
throw new NoSuchElementException();
}
}
@Override
public void remove()
@ -496,7 +500,7 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
throw new UnsupportedOperationException();
}
}
/**
* Compares two <code>SXSSFRow</code> objects. Two rows are equal if they belong to the same worksheet and
* their row indexes are equal.
@ -524,9 +528,9 @@ public class SXSSFRow implements Row, Comparable<SXSSFRow>
throw new IllegalArgumentException("The compared rows must belong to the same sheet");
}
Integer thisRow = this.getRowNum();
Integer otherRow = other.getRowNum();
return thisRow.compareTo(otherRow);
int thisRow = this.getRowNum();
int otherRow = other.getRowNum();
return Integer.compare(thisRow, otherRow);
}
@Override

View File

@ -19,6 +19,7 @@ package org.apache.poi.xssf.usermodel;
import org.apache.poi.ss.formula.BaseFormulaEvaluator;
import org.apache.poi.ss.formula.EvaluationCell;
import org.apache.poi.ss.formula.EvaluationWorkbook;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
@ -26,6 +27,7 @@ import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.StringEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.RichTextString;
@ -69,4 +71,16 @@ public abstract class BaseXSSFFormulaEvaluator extends BaseFormulaEvaluator {
}
throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
}
protected void setCellType(Cell cell, CellType cellType) {
if (cell instanceof XSSFCell) {
EvaluationWorkbook evaluationWorkbook = getEvaluationWorkbook();
BaseXSSFEvaluationWorkbook xewb = BaseXSSFEvaluationWorkbook.class.isAssignableFrom(evaluationWorkbook.getClass()) ? (BaseXSSFEvaluationWorkbook) evaluationWorkbook : null;
((XSSFCell) cell).setCellType(cellType, xewb);
} else {
// could be an SXSSFCell
cell.setCellType(cellType);
}
}
}

View File

@ -37,6 +37,7 @@ import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FormulaError;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
@ -477,7 +478,7 @@ public final class XSSFCell implements Cell {
* @return a formula for the cell
* @throws IllegalStateException if the cell type returned by {@link #getCellType()} is not {@link CellType#FORMULA}
*/
protected String getCellFormula(XSSFEvaluationWorkbook fpb) {
protected String getCellFormula(BaseXSSFEvaluationWorkbook fpb) {
CellType cellType = getCellType();
if(cellType != CellType.FORMULA) {
throw typeMismatch(CellType.FORMULA, cellType, false);
@ -506,7 +507,7 @@ public final class XSSFCell implements Cell {
* @param si Shared Group Index
* @return non shared formula created for the given shared formula and this cell
*/
private String convertSharedFormula(int si, XSSFEvaluationWorkbook fpb){
private String convertSharedFormula(int si, BaseXSSFEvaluationWorkbook fpb){
XSSFSheet sheet = getSheet();
CTCellFormula f = sheet.getSharedFormula(si);
@ -536,6 +537,10 @@ public final class XSSFCell implements Cell {
* Note, this method only sets the formula string and does not calculate the formula value.
* To set the precalculated value use {@link #setCellValue(double)} or {@link #setCellValue(String)}
* </p>
* <p>
* Note, if there are any shared formulas, his will invalidate any
* {@link FormulaEvaluator} instances based on this workbook.
* </p>
*
* @param formula the formula to set, e.g. <code>"SUM(C4:E4)"</code>.
* If the argument is <code>null</code> then the current formula is removed.
@ -563,7 +568,7 @@ public final class XSSFCell implements Cell {
if (formula == null) {
wb.onDeleteFormula(this);
if (_cell.isSetF()) {
_row.getSheet().onDeleteFormula(this);
_row.getSheet().onDeleteFormula(this, null);
_cell.unsetF();
}
return;
@ -962,6 +967,16 @@ public final class XSSFCell implements Cell {
*/
@Override
public void setCellType(CellType cellType) {
setCellType(cellType, null);
}
/**
* Needed by bug #62834, which points out getCellFormula() expects an evaluation context or creates a new one,
* so if there is one in use, it needs to be carried on through.
* @param cellType
* @param evalWb BaseXSSFEvaluationWorkbook already in use, or null if a new implicit one should be used
*/
protected void setCellType(CellType cellType, BaseXSSFEvaluationWorkbook evalWb) {
CellType prevType = getCellType();
if(isPartOfArrayFormulaGroup()){
@ -969,7 +984,7 @@ public final class XSSFCell implements Cell {
}
if(prevType == CellType.FORMULA && cellType != CellType.FORMULA) {
if (_cell.isSetF()) {
_row.getSheet().onDeleteFormula(this);
_row.getSheet().onDeleteFormula(this, evalWb);
}
getSheet().getWorkbook().onDeleteFormula(this);
}

View File

@ -446,7 +446,7 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing<XSS
XSSFSheet sheet = getSheet();
XSSFWorkbook wb = sheet.getWorkbook();
int sheetIndex = wb.getSheetIndex(sheet);
long shapeId = (sheetIndex + 1) * 1024 + newShapeId();
long shapeId = (sheetIndex + 1L) * 1024 + newShapeId();
// add reference to OLE part
PackagePartName olePN;

View File

@ -22,8 +22,8 @@ import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellStyle;
@ -77,7 +77,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
_cells.put(colI, cell);
sheet.onReadCell(cell);
}
if (! row.isSetR()) {
// Certain file format writers skip the row number
// Assume no gaps, and give this the next row number
@ -158,9 +158,9 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
throw new IllegalArgumentException("The compared rows must belong to the same sheet");
}
Integer thisRow = this.getRowNum();
Integer otherRow = other.getRowNum();
return thisRow.compareTo(otherRow);
int thisRow = this.getRowNum();
int otherRow = other.getRowNum();
return Integer.compare(thisRow, otherRow);
}
@Override
@ -245,7 +245,9 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
*/
@Override
public XSSFCell getCell(int cellnum, MissingCellPolicy policy) {
if(cellnum < 0) throw new IllegalArgumentException("Cell index must be >= 0");
if(cellnum < 0) {
throw new IllegalArgumentException("Cell index must be >= 0");
}
// Performance optimization for bug 57840: explicit boxing is slightly faster than auto-unboxing, though may use more memory
final Integer colI = Integer.valueOf(cellnum); // NOSONAR
@ -332,8 +334,12 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
@Override
public void setHeight(short height) {
if (height == -1) {
if (_row.isSetHt()) _row.unsetHt();
if (_row.isSetCustomHeight()) _row.unsetCustomHeight();
if (_row.isSetHt()) {
_row.unsetHt();
}
if (_row.isSetCustomHeight()) {
_row.unsetCustomHeight();
}
} else {
_row.setHt((double) height / 20);
_row.setCustomHeight(true);
@ -425,8 +431,10 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
*/
@Override
public XSSFCellStyle getRowStyle() {
if(!isFormatted()) return null;
if(!isFormatted()) {
return null;
}
StylesTable stylesSource = getSheet().getWorkbook().getStylesSource();
if(stylesSource.getNumCellStyles() > 0) {
return stylesSource.getStyleAt((int)_row.getS());
@ -434,7 +442,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
return null;
}
}
/**
* Applies a whole-row cell styling to the row.
* If the value is null then the style information is removed,
@ -449,7 +457,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
}
} else {
StylesTable styleSource = getSheet().getWorkbook().getStylesSource();
XSSFCellStyle xStyle = (XSSFCellStyle)style;
xStyle.verifyBelongsToStylesSource(styleSource);
@ -458,7 +466,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
_row.setCustomFormat(true);
}
}
/**
* Remove the Cell from this row.
*
@ -502,8 +510,8 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
int i = 0;
for (XSSFCell xssfCell : _cells.values()) {
cArray[i] = (CTCell) xssfCell.getCTCell().copy();
// we have to copy and re-create the XSSFCell here because the
// we have to copy and re-create the XSSFCell here because the
// elements as otherwise setCArray below invalidates all the columns!
// see Bug 56170, XMLBeans seems to always release previous objects
// in the CArray, so we need to provide completely new ones here!
@ -537,7 +545,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
}
setRowNum(rownum);
}
/**
* Copy the cells from srcRow to this row
* If this row is not a blank row, this will merge the two rows, overwriting
@ -589,7 +597,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
final int srcRowNum = srcRow.getRowNum();
final int destRowNum = getRowNum();
final int rowDifference = destRowNum - srcRowNum;
final FormulaShifter formulaShifter = FormulaShifter.createForRowCopy(sheetIndex, sheetName, srcRowNum, srcRowNum, rowDifference, SpreadsheetVersion.EXCEL2007);
final XSSFRowShifter rowShifter = new XSSFRowShifter(_sheet);
rowShifter.updateRowFormulas(this, formulaShifter);
@ -617,7 +625,7 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
public int getOutlineLevel() {
return _row.getOutlineLevel();
}
/**
* Shifts column range [firstShiftColumnIndex-lastShiftColumnIndex] step places to the right.
* @param firstShiftColumnIndex the column to start shifting
@ -626,20 +634,23 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
*/
@Override
public void shiftCellsRight(int firstShiftColumnIndex, int lastShiftColumnIndex, int step) {
if(step < 0)
if(step < 0) {
throw new IllegalArgumentException("Shifting step may not be negative ");
if(firstShiftColumnIndex > lastShiftColumnIndex)
}
if(firstShiftColumnIndex > lastShiftColumnIndex) {
throw new IllegalArgumentException(String.format(LocaleUtil.getUserLocale(),
"Incorrect shifting range : %d-%d", firstShiftColumnIndex, lastShiftColumnIndex));
for (int columnIndex = lastShiftColumnIndex; columnIndex >= firstShiftColumnIndex; columnIndex--){ // process cells backwards, because of shifting
}
for (int columnIndex = lastShiftColumnIndex; columnIndex >= firstShiftColumnIndex; columnIndex--){ // process cells backwards, because of shifting
shiftCell(columnIndex, step);
}
for (int columnIndex = firstShiftColumnIndex; columnIndex <= firstShiftColumnIndex+step-1; columnIndex++)
{
_cells.remove(columnIndex);
XSSFCell targetCell = getCell(columnIndex);
if(targetCell != null)
if(targetCell != null) {
targetCell.getCTCell().set(CTCell.Factory.newInstance());
}
}
}
/**
@ -650,27 +661,32 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
*/
@Override
public void shiftCellsLeft(int firstShiftColumnIndex, int lastShiftColumnIndex, int step) {
if(step < 0)
if(step < 0) {
throw new IllegalArgumentException("Shifting step may not be negative ");
if(firstShiftColumnIndex > lastShiftColumnIndex)
}
if(firstShiftColumnIndex > lastShiftColumnIndex) {
throw new IllegalArgumentException(String.format(LocaleUtil.getUserLocale(),
"Incorrect shifting range : %d-%d", firstShiftColumnIndex, lastShiftColumnIndex));
if(firstShiftColumnIndex - step < 0)
}
if(firstShiftColumnIndex - step < 0) {
throw new IllegalStateException("Column index less than zero : " + (Integer.valueOf(firstShiftColumnIndex + step)).toString());
for (int columnIndex = firstShiftColumnIndex; columnIndex <= lastShiftColumnIndex; columnIndex++){
}
for (int columnIndex = firstShiftColumnIndex; columnIndex <= lastShiftColumnIndex; columnIndex++){
shiftCell(columnIndex, -step);
}
for (int columnIndex = lastShiftColumnIndex-step+1; columnIndex <= lastShiftColumnIndex; columnIndex++){
_cells.remove(columnIndex);
XSSFCell targetCell = getCell(columnIndex);
if(targetCell != null)
if(targetCell != null) {
targetCell.getCTCell().set(CTCell.Factory.newInstance());
}
}
}
private void shiftCell(int columnIndex, int step/*pass negative value for left shift*/){
if(columnIndex + step < 0) // only for shifting left
if(columnIndex + step < 0) {
throw new IllegalStateException("Column index less than zero : " + (Integer.valueOf(columnIndex + step)).toString());
}
XSSFCell currentCell = getCell(columnIndex);
if(currentCell != null){
currentCell.setCellNum(columnIndex+step);
@ -679,8 +695,9 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
else {
_cells.remove(columnIndex+step);
XSSFCell targetCell = getCell(columnIndex+step);
if(targetCell != null)
if(targetCell != null) {
targetCell.getCTCell().set(CTCell.Factory.newInstance());
}
}
}
}

View File

@ -147,6 +147,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument;
* contain text, numbers, dates, and formulas. Cells can also be formatted.
* </p>
*/
@SuppressWarnings("deprecation")
public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
private static final POILogger logger = POILogFactory.getLogger(XSSFSheet.class);
@ -472,7 +473,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
/**
* Verify that candidate region does not intersect with an existing merged region in this sheet
*
* @param candidateRegion
* @param candidateRegion the range of cells to verify
* @throws IllegalStateException if candidate region intersects an existing merged region in this sheet (or candidateRegion is already merged in this sheet)
*/
private void validateMergedRegions(CellRangeAddress candidateRegion) {
@ -855,8 +856,8 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
/**
* Get a Hyperlink in this sheet anchored at row, column
*
* @param row
* @param column
* @param row The row where the hyperlink is anchored
* @param column The column where the hyperlinkn is anchored
* @return hyperlink if there is a hyperlink anchored at row, column; otherwise returns null
*/
@Override
@ -1480,8 +1481,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
*
* @param startRowNum the first row number in this sheet to return
* @param endRowNum the last row number in this sheet to return
* @param createRowIfMissing
* @return All rows between startRow and endRow, inclusive
* @param createRowIfMissing If missing rows should be created.
* @return All rows between startRow and endRow, inclusive. If createRowIfMissing is false,
* only previously existing rows are returned, otherwise empty rows are added as necessary
* @throws IllegalArgumentException if startRowNum and endRowNum are not in ascending order
*/
private List<XSSFRow> getRows(int startRowNum, int endRowNum, boolean createRowIfMissing) {
@ -2472,7 +2474,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
* 'Collapsed' state is stored in a single column col info record
* immediately after the outline group
*
* @param idx
* @param idx The column-index to check
* @return a boolean represented if the column is collapsed
*/
private boolean isColumnGroupCollapsed(int idx) {
@ -3052,7 +3054,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
rebuildRows();
}
private final void rebuildRows() {
private void rebuildRows() {
//rebuild the _rows map
List<XSSFRow> rowList = new ArrayList<>(_rows.values());
_rows.clear();
@ -3114,25 +3116,22 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
// then do the actual moving and also adjust comments/rowHeight
// we need to sort it in a way so the shifting does not mess up the structures,
// i.e. when shifting down, start from down and go up, when shifting up, vice-versa
SortedMap<XSSFComment, Integer> commentsToShift = new TreeMap<>(new Comparator<XSSFComment>() {
@Override
public int compare(XSSFComment o1, XSSFComment o2) {
int row1 = o1.getRow();
int row2 = o2.getRow();
SortedMap<XSSFComment, Integer> commentsToShift = new TreeMap<>((o1, o2) -> {
int row1 = o1.getRow();
int row2 = o2.getRow();
if (row1 == row2) {
// ordering is not important when row is equal, but don't return zero to still
// get multiple comments per row into the map
return o1.hashCode() - o2.hashCode();
}
if (row1 == row2) {
// ordering is not important when row is equal, but don't return zero to still
// get multiple comments per row into the map
return o1.hashCode() - o2.hashCode();
}
// when shifting down, sort higher row-values first
if (n > 0) {
return row1 < row2 ? 1 : -1;
} else {
// sort lower-row values first when shifting up
return row1 > row2 ? 1 : -1;
}
// when shifting down, sort higher row-values first
if (n > 0) {
return row1 < row2 ? 1 : -1;
} else {
// sort lower-row values first when shifting up
return row1 > row2 ? 1 : -1;
}
});
@ -3211,25 +3210,22 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
// then do the actual moving and also adjust comments/rowHeight
// we need to sort it in a way so the shifting does not mess up the structures,
// i.e. when shifting down, start from down and go up, when shifting up, vice-versa
SortedMap<XSSFComment, Integer> commentsToShift = new TreeMap<>(new Comparator<XSSFComment>() {
@Override
public int compare(XSSFComment o1, XSSFComment o2) {
int column1 = o1.getColumn();
int column2 = o2.getColumn();
SortedMap<XSSFComment, Integer> commentsToShift = new TreeMap<>((o1, o2) -> {
int column1 = o1.getColumn();
int column2 = o2.getColumn();
if (column1 == column2) {
// ordering is not important when row is equal, but don't return zero to still
// get multiple comments per row into the map
return o1.hashCode() - o2.hashCode();
}
if (column1 == column2) {
// ordering is not important when row is equal, but don't return zero to still
// get multiple comments per row into the map
return o1.hashCode() - o2.hashCode();
}
// when shifting down, sort higher row-values first
if (n > 0) {
return column1 < column2 ? 1 : -1;
} else {
// sort lower-row values first when shifting up
return column1 > column2 ? 1 : -1;
}
// when shifting down, sort higher row-values first
if (n > 0) {
return column1 < column2 ? 1 : -1;
} else {
// sort lower-row values first when shifting up
return column1 > column2 ? 1 : -1;
}
});
@ -4096,7 +4092,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
* Creates a new Table, and associates it with this Sheet.
*
* @param tableArea
* the area that the table should cover, should not be {@null}
* the area that the table should cover, should not be null
* @return the created table
* @since 4.0.0
*/
@ -4421,18 +4417,15 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
+ "defined source sheet " + sourceSheet.getSheetName() + ".");
}
return createPivotTable(position, sourceSheet, new PivotTableReferenceConfigurator() {
@Override
public void configureReference(CTWorksheetSource wsSource) {
final String[] firstCell = source.getFirstCell().getCellRefParts();
final String firstRow = firstCell[1];
final String firstCol = firstCell[2];
final String[] lastCell = source.getLastCell().getCellRefParts();
final String lastRow = lastCell[1];
final String lastCol = lastCell[2];
final String ref = firstCol+firstRow+':'+lastCol+lastRow; //or just source.formatAsString()
wsSource.setRef(ref);
}
return createPivotTable(position, sourceSheet, wsSource -> {
final String[] firstCell = source.getFirstCell().getCellRefParts();
final String firstRow = firstCell[1];
final String firstCol = firstCell[2];
final String[] lastCell = source.getLastCell().getCellRefParts();
final String lastRow = lastCell[1];
final String lastCol = lastCell[2];
final String ref = firstCol+firstRow+':'+lastCol+lastRow; //or just source.formatAsString()
wsSource.setRef(ref);
});
}
@ -4494,12 +4487,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
+ "defined source sheet " + sourceSheet.getSheetName() + ".");
}
return createPivotTable(position, sourceSheet, new PivotTableReferenceConfigurator() {
@Override
public void configureReference(CTWorksheetSource wsSource) {
wsSource.setName(source.getNameName());
}
});
return createPivotTable(position, sourceSheet, wsSource -> wsSource.setName(source.getNameName()));
}
/**
@ -4523,12 +4511,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
*/
@Beta
public XSSFPivotTable createPivotTable(final Table source, CellReference position) {
return createPivotTable(position, getWorkbook().getSheet(source.getSheetName()), new PivotTableReferenceConfigurator() {
@Override
public void configureReference(CTWorksheetSource wsSource) {
wsSource.setName(source.getName());
}
});
return createPivotTable(position, getWorkbook().getSheet(source.getSheetName()), wsSource -> wsSource.setName(source.getName()));
}
/**
@ -4621,8 +4604,10 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
/**
* when a cell with a 'master' shared formula is removed, the next cell in the range becomes the master
* @param cell The cell that is removed
* @param evalWb BaseXSSFEvaluationWorkbook in use, if one exists
*/
protected void onDeleteFormula(XSSFCell cell){
protected void onDeleteFormula(XSSFCell cell, BaseXSSFEvaluationWorkbook evalWb){
CTCellFormula f = cell.getCTCell().getF();
if (f != null && f.getT() == STCellFormulaType.SHARED && f.isSetRef() && f.getStringValue() != null) {
@ -4634,9 +4619,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
XSSFRow row = getRow(i);
if(row != null) for(int j = cell.getColumnIndex(); j <= ref.getLastColumn(); j++){
XSSFCell nextCell = row.getCell(j);
if(nextCell != null && nextCell != cell){
if(nextCell != null && nextCell != cell && nextCell.getCellType() == CellType.FORMULA){
CTCellFormula nextF = nextCell.getCTCell().getF();
nextF.setStringValue(nextCell.getCellFormula());
nextF.setStringValue(nextCell.getCellFormula(evalWb));
CellRangeAddress nextRef = new CellRangeAddress(
nextCell.getRowIndex(), ref.getLastRow(),
nextCell.getColumnIndex(), ref.getLastColumn());

View File

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

View File

@ -50,7 +50,7 @@ public class ColumnHelper {
TreeSet<CTCol> trackedCols = new TreeSet<>(CTColComparator.BY_MIN_MAX);
CTCols newCols = CTCols.Factory.newInstance();
CTCols[] colsArray = worksheet.getColsArray();
int i = 0;
int i;
for (i = 0; i < colsArray.length; i++) {
CTCols cols = colsArray[i];
for (CTCol col : cols.getColList()) {
@ -61,7 +61,7 @@ public class ColumnHelper {
worksheet.removeCols(y);
}
newCols.setColArray(trackedCols.toArray(new CTCol[trackedCols.size()]));
newCols.setColArray(trackedCols.toArray(new CTCol[0]));
worksheet.addNewCols();
worksheet.setColsArray(0, newCols);
}

View File

@ -40,21 +40,27 @@ public class XWPFSDTContent implements ISDTContent {
// private final IBody part;
// private final XWPFDocument document;
private List<XWPFParagraph> paragraphs = new ArrayList<>();
private List<XWPFTable> tables = new ArrayList<>();
private List<XWPFRun> runs = new ArrayList<>();
private List<XWPFSDT> contentControls = new ArrayList<>();
// private List<XWPFParagraph> paragraphs = new ArrayList<>();
// private List<XWPFTable> tables = new ArrayList<>();
// private List<XWPFRun> runs = new ArrayList<>();
// private List<XWPFSDT> contentControls = new ArrayList<>();
private List<ISDTContents> bodyElements = new ArrayList<>();
public XWPFSDTContent(CTSdtContentRun sdtRun, IBody part, IRunBody parent) {
if (sdtRun == null) {
return;
}
for (CTR ctr : sdtRun.getRArray()) {
XWPFRun run = new XWPFRun(ctr, parent);
runs.add(run);
// runs.add(run);
bodyElements.add(run);
}
}
public XWPFSDTContent(CTSdtContentBlock block, IBody part, IRunBody parent) {
if (block == null) {
return;
}
XmlCursor cursor = block.newCursor();
cursor.selectPath("./*");
while (cursor.toNextSelection()) {
@ -62,24 +68,25 @@ public class XWPFSDTContent implements ISDTContent {
if (o instanceof CTP) {
XWPFParagraph p = new XWPFParagraph((CTP) o, part);
bodyElements.add(p);
paragraphs.add(p);
// paragraphs.add(p);
} else if (o instanceof CTTbl) {
XWPFTable t = new XWPFTable((CTTbl) o, part);
bodyElements.add(t);
tables.add(t);
// tables.add(t);
} else if (o instanceof CTSdtBlock) {
XWPFSDT c = new XWPFSDT(((CTSdtBlock) o), part);
bodyElements.add(c);
contentControls.add(c);
// contentControls.add(c);
} else if (o instanceof CTR) {
XWPFRun run = new XWPFRun((CTR) o, parent);
runs.add(run);
// runs.add(run);
bodyElements.add(run);
}
}
cursor.dispose();
}
@Override
public String getText() {
StringBuilder text = new StringBuilder();
boolean addNewLine = false;
@ -130,6 +137,7 @@ public class XWPFSDTContent implements ISDTContent {
}
}
@Override
public String toString() {
return getText();
}

View File

@ -161,8 +161,9 @@ public class XWPFTable implements IBodyElement, ISDTContents {
this.ctTbl = table;
// is an empty table: I add one row and one column as default
if (table.sizeOfTrArray() == 0)
if (table.sizeOfTrArray() == 0) {
createEmptyTable(table);
}
for (CTRow row : table.getTrList()) {
StringBuilder rowText = new StringBuilder();
@ -233,7 +234,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
return text.toString();
}
/**
* This method has existed since 2008 without an implementation.
* It will be removed unless an implementation is provided.
@ -288,7 +289,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get the width value as an integer.
* <p>If the width type is AUTO, DXA, or NIL, the value is 20ths of a point. If
* the width type is PCT, the value is the percentage times 50 (e.g., 2500 for 50%).</p>
* the width type is PCT, the value is the percentage times 50 (e.g., 2500 for 50%).</p>
* @return width value as an integer
*/
public int getWidth() {
@ -322,7 +323,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
}
/**
* Returns CTTblPr object for table. If force parameter is true, will
* Returns CTTblPr object for table. If force parameter is true, will
* create the element if necessary. If force parameter is false, returns
* null when CTTblPr element is missing.
*
@ -343,7 +344,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
private CTTblBorders getTblBorders(boolean force) {
CTTblPr tblPr = getTblPr(force);
return tblPr == null ? null
: tblPr.isSetTblBorders() ? tblPr.getTblBorders()
: tblPr.isSetTblBorders() ? tblPr.getTblBorders()
: force ? tblPr.addNewTblBorders()
: null;
}
@ -413,18 +414,18 @@ public class XWPFTable implements IBodyElement, ISDTContents {
: tPr.isSetJc() ? TableRowAlign.valueOf(tPr.getJc().getVal().intValue())
: null;
}
/**
* Set table alignment to specified {@link TableRowAlign}
*
* @param ha {@link TableRowAlign} to set
* @param tra {@link TableRowAlign} to set
*/
public void setTableAlignment(TableRowAlign tra) {
CTTblPr tPr = getTblPr(true);
CTJc jc = tPr.isSetJc() ? tPr.getJc() : tPr.addNewJc();
jc.setVal(STJc.Enum.forInt(tra.getValue()));
}
/**
* Removes the table alignment attribute from a table
*/
@ -434,7 +435,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
tPr.unsetJc();
}
}
private void addColumn(XWPFTableRow tabRow, int sizeCol) {
if (sizeCol > 0) {
for (int i = 0; i < sizeCol; i++) {
@ -486,7 +487,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get inside horizontal border size
*
*
* @return The width of the Inside Horizontal borders in 1/8th points,
* -1 if missing.
*/
@ -496,7 +497,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get inside horizontal border spacing
*
*
* @return The offset to the Inside Horizontal borders in points,
* -1 if missing.
*/
@ -506,7 +507,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get inside horizontal border color
*
*
* @return The color of the Inside Horizontal borders, null if missing.
*/
public String getInsideHBorderColor() {
@ -524,7 +525,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get inside vertical border size
*
*
* @return The width of the Inside vertical borders in 1/8th points,
* -1 if missing.
*/
@ -534,7 +535,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get inside vertical border spacing
*
*
* @return The offset to the Inside vertical borders in points,
* -1 if missing.
*/
@ -544,7 +545,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get inside vertical border color
*
*
* @return The color of the Inside vertical borders, null if missing.
*/
public String getInsideVBorderColor() {
@ -562,7 +563,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get top border size
*
*
* @return The width of the top borders in 1/8th points,
* -1 if missing.
*/
@ -572,7 +573,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get top border spacing
*
*
* @return The offset to the top borders in points,
* -1 if missing.
*/
@ -582,7 +583,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get top border color
*
*
* @return The color of the top borders, null if missing.
*/
public String getTopBorderColor() {
@ -600,7 +601,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get bottom border size
*
*
* @return The width of the bottom borders in 1/8th points,
* -1 if missing.
*/
@ -610,7 +611,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get bottom border spacing
*
*
* @return The offset to the bottom borders in points,
* -1 if missing.
*/
@ -620,7 +621,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get bottom border color
*
*
* @return The color of the bottom borders, null if missing.
*/
public String getBottomBorderColor() {
@ -638,7 +639,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get Left border size
*
*
* @return The width of the Left borders in 1/8th points,
* -1 if missing.
*/
@ -648,7 +649,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get Left border spacing
*
*
* @return The offset to the Left borders in points,
* -1 if missing.
*/
@ -658,7 +659,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get Left border color
*
*
* @return The color of the Left borders, null if missing.
*/
public String getLeftBorderColor() {
@ -676,7 +677,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get Right border size
*
*
* @return The width of the Right borders in 1/8th points,
* -1 if missing.
*/
@ -686,7 +687,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get Right border spacing
*
*
* @return The offset to the Right borders in points,
* -1 if missing.
*/
@ -696,7 +697,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
/**
* Get Right border color
*
*
* @return The color of the Right borders, null if missing.
*/
public String getRightBorderColor() {
@ -770,7 +771,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
* of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value.
* @param space - Specifies the spacing offset that shall be used to place this border on the table
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* or auto to allow a consumer to automatically determine the border color as appropriate.
*/
public void setInsideHBorder(XWPFBorderType type, int size, int space, String rgbColor) {
@ -786,7 +787,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
* of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value.
* @param space - Specifies the spacing offset that shall be used to place this border on the table
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* or auto to allow a consumer to automatically determine the border color as appropriate.
*/
public void setInsideVBorder(XWPFBorderType type, int size, int space, String rgbColor) {
@ -802,7 +803,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
* of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value.
* @param space - Specifies the spacing offset that shall be used to place this border on the table
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* or auto to allow a consumer to automatically determine the border color as appropriate.
*/
public void setTopBorder(XWPFBorderType type, int size, int space, String rgbColor) {
@ -818,7 +819,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
* of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value.
* @param space - Specifies the spacing offset that shall be used to place this border on the table
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* or auto to allow a consumer to automatically determine the border color as appropriate.
*/
public void setBottomBorder(XWPFBorderType type, int size, int space, String rgbColor) {
@ -834,7 +835,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
* of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value.
* @param space - Specifies the spacing offset that shall be used to place this border on the table
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* or auto to allow a consumer to automatically determine the border color as appropriate.
*/
public void setLeftBorder(XWPFBorderType type, int size, int space, String rgbColor) {
@ -850,7 +851,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
* of a point) and a maximum value of 96 (twelve points). Any values outside this
* range may be reassigned to a more appropriate value.
* @param space - Specifies the spacing offset that shall be used to place this border on the table
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* @param rgbColor - This color may either be presented as a hex value (in RRGGBB format),
* or auto to allow a consumer to automatically determine the border color as appropriate.
*/
public void setRightBorder(XWPFBorderType type, int size, int space, String rgbColor) {
@ -872,14 +873,14 @@ public class XWPFTable implements IBodyElement, ISDTContents {
public void removeInsideHBorder() {
removeBorder(Border.INSIDE_H);
}
/**
* Remove inside vertical borders for table
*/
public void removeInsideVBorder() {
removeBorder(Border.INSIDE_V);
}
/**
* Remove top borders for table
*/
@ -893,21 +894,21 @@ public class XWPFTable implements IBodyElement, ISDTContents {
public void removeBottomBorder() {
removeBorder(Border.BOTTOM);
}
/**
* Remove left borders for table
*/
public void removeLeftBorder() {
removeBorder(Border.LEFT);
}
/**
* Remove right borders for table
*/
public void removeRightBorder() {
removeBorder(Border.RIGHT);
}
/**
* Remove all borders from table
*/
@ -959,7 +960,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
}
/**
* removes the Borders node from Table properties if there are
* removes the Borders node from Table properties if there are
* no border elements
*/
private void cleanupTblBorders() {
@ -976,7 +977,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
}
}
}
public int getCellMarginTop() {
return getCellMargin(CTTblCellMar::getTop);
}
@ -1095,10 +1096,12 @@ public class XWPFTable implements IBodyElement, ISDTContents {
*
* @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
*/
@Override
public BodyElementType getElementType() {
return BodyElementType.TABLE;
}
@Override
public IBody getBody() {
return part;
}
@ -1108,6 +1111,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
*
* @see org.apache.poi.xwpf.usermodel.IBody#getPart()
*/
@Override
public POIXMLDocumentPart getPart() {
if (part != null) {
return part.getPart();
@ -1120,6 +1124,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
*
* @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
*/
@Override
public BodyType getPartType() {
return part.getPartType();
}
@ -1130,11 +1135,13 @@ public class XWPFTable implements IBodyElement, ISDTContents {
*/
public XWPFTableRow getRow(CTRow row) {
for (int i = 0; i < getRows().size(); i++) {
if (getRows().get(i).getCtRow() == row) return getRow(i);
if (getRows().get(i).getCtRow() == row) {
return getRow(i);
}
}
return null;
}
/**
* Get the table width as a decimal value.
* <p>If the width type is DXA or AUTO, then the value will always have
@ -1159,14 +1166,14 @@ public class XWPFTable implements IBodyElement, ISDTContents {
protected static double getWidthDecimal(CTTblWidth ctWidth) {
double result = 0.0;
STTblWidth.Enum typeValue = ctWidth.getType();
if (typeValue == STTblWidth.DXA
|| typeValue == STTblWidth.AUTO
if (typeValue == STTblWidth.DXA
|| typeValue == STTblWidth.AUTO
|| typeValue == STTblWidth.NIL) {
result = 0.0 + ctWidth.getW().intValue();
} else if (typeValue == STTblWidth.PCT) {
// Percentage values are stored as integers that are 50 times
// percentage.
result = ctWidth.getW().intValue() / 50.0;
result = ctWidth.getW().intValue() / 50.0;
} else {
// Should never get here
}
@ -1230,7 +1237,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
protected static void setWidthValue(String widthValue, CTTblWidth ctWidth) {
if (!widthValue.matches(REGEX_WIDTH_VALUE)) {
throw new RuntimeException("Table width value \"" + widthValue + "\" "
+ "must match regular expression \"" + REGEX_WIDTH_VALUE + "\".");
+ "must match regular expression \"" + REGEX_WIDTH_VALUE + "\".");
}
if (widthValue.matches("auto")) {
ctWidth.setType(STTblWidth.AUTO);
@ -1240,13 +1247,13 @@ public class XWPFTable implements IBodyElement, ISDTContents {
} else {
// Must be an integer
ctWidth.setW(new BigInteger(widthValue));
ctWidth.setType(STTblWidth.DXA);
ctWidth.setType(STTblWidth.DXA);
}
}
/**
* Set the underlying table width value to a percentage value.
* @param ctWidth The CTTblWidth to set the value on
* @param ctWidth The CTTblWidth to set the value on
* @param widthValue String width value in form "33.3%" or an integer that is 50 times desired percentage value (e.g,
* 2500 for 50%)
* @since 4.0.0
@ -1257,7 +1264,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
String numberPart = widthValue.substring(0, widthValue.length() - 1);
double percentage = Double.parseDouble(numberPart) * 50;
long intValue = Math.round(percentage);
ctWidth.setW(BigInteger.valueOf(intValue));
ctWidth.setW(BigInteger.valueOf(intValue));
} else if (widthValue.matches("[0-9]+")) {
ctWidth.setW(new BigInteger(widthValue));
} else {
@ -1275,7 +1282,7 @@ public class XWPFTable implements IBodyElement, ISDTContents {
* @since 4.0.0
*/
public void setWidthType(TableWidthType widthType) {
setWidthType(widthType, getTblPr().getTblW());
setWidthType(widthType, getTblPr().getTblW());
}
/**

View File

@ -17,7 +17,25 @@
package org.apache.poi.ooxml.util;
import junit.framework.TestCase;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.StringUtil;
import org.apache.poi.util.SuppressForbidden;
@ -29,19 +47,7 @@ import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.reflections.Reflections;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
import junit.framework.TestCase;
/**
* Build a 'lite' version of the ooxml-schemas.jar
@ -74,12 +80,12 @@ public final class OOXMLLite {
}
public static void main(String[] args) throws IOException {
System.out.println("Free memory (bytes): " +
System.out.println("Free memory (bytes): " +
Runtime.getRuntime().freeMemory());
long maxMemory = Runtime.getRuntime().maxMemory();
System.out.println("Maximum memory (bytes): " +
System.out.println("Maximum memory (bytes): " +
(maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory));
System.out.println("Total memory (bytes): " +
System.out.println("Total memory (bytes): " +
Runtime.getRuntime().totalMemory());
String dest = null, test = null, ooxml = null;
@ -87,13 +93,13 @@ public final class OOXMLLite {
for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case "-dest":
dest = args[++i];
dest = args[++i]; // lgtm[java/index-out-of-bounds]
break;
case "-test":
test = args[++i];
test = args[++i]; // lgtm[java/index-out-of-bounds]
break;
case "-ooxml":
ooxml = args[++i];
ooxml = args[++i]; // lgtm[java/index-out-of-bounds]
break;
}
}
@ -248,7 +254,7 @@ public final class OOXMLLite {
return true;
}
}
// also check super classes
if(testclass.getSuperclass() != null) {
for (Method m : testclass.getSuperclass().getDeclaredMethods()) {
@ -257,7 +263,7 @@ public final class OOXMLLite {
}
}
}
System.out.println("Class " + testclass.getName() + " does not derive from TestCase and does not have a @Test annotation");
// Should we also look at superclasses to find cases
@ -286,8 +292,12 @@ public final class OOXMLLite {
String path = arg.getAbsolutePath();
String prefix = root.getAbsolutePath();
String cls = path.substring(prefix.length() + 1).replace(File.separator, ".");
if(!cls.matches(ptrn)) return;
if (cls.matches(exclude)) return;
if(!cls.matches(ptrn)) {
return;
}
if (cls.matches(exclude)) {
return;
}
//ignore inner classes defined in tests
if (cls.indexOf('$') != -1) {
System.out.println("Inner class " + cls + " not included");
@ -315,10 +325,11 @@ public final class OOXMLLite {
*/
@SuppressWarnings("unchecked")
private static Set<Class<?>> getLoadedClasses(String ptrn) {
// make the field accessible, we defer this from static initialization to here to
// make the field accessible, we defer this from static initialization to here to
// allow JDKs which do not have this field (e.g. IBM JDK) to at least load the class
// without failing, see https://issues.apache.org/bugzilla/show_bug.cgi?id=56550
final Field _classes = AccessController.doPrivileged(new PrivilegedAction<Field>() {
@Override
@SuppressForbidden("TODO: Reflection works until Java 8 on Oracle/Sun JDKs, but breaks afterwards (different classloader types, access checks)")
public Field run() {
try {
@ -339,11 +350,17 @@ public final class OOXMLLite {
for (Class<?> cls : classes) {
// e.g. proxy-classes, ...
ProtectionDomain pd = cls.getProtectionDomain();
if (pd == null) continue;
if (pd == null) {
continue;
}
CodeSource cs = pd.getCodeSource();
if (cs == null) continue;
if (cs == null) {
continue;
}
URL loc = cs.getLocation();
if (loc == null) continue;
if (loc == null) {
continue;
}
String jar = loc.toString();
if (jar.contains(ptrn)) {

View File

@ -30,7 +30,6 @@ import java.io.IOException;
import java.util.Set;
import java.util.TreeMap;
import junit.framework.AssertionFailedError;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.poi.util.IOUtils;
@ -44,125 +43,130 @@ import org.xmlunit.diff.Diff;
import org.xmlunit.diff.DifferenceEvaluator;
import org.xmlunit.diff.ElementSelectors;
import junit.framework.AssertionFailedError;
/**
* Compare the contents of 2 zip files.
*/
public final class ZipFileAssert {
private ZipFileAssert() {
}
private ZipFileAssert() {
}
private static void equals(
TreeMap<String, ByteArrayOutputStream> file1,
TreeMap<String, ByteArrayOutputStream> file2) {
Set<String> listFile1 = file1.keySet();
Assert.assertEquals("not the same number of files in zip:", listFile1.size(), file2.keySet().size());
for (String fileName : listFile1) {
// extract the contents for both
ByteArrayOutputStream contain1 = file1.get(fileName);
ByteArrayOutputStream contain2 = file2.get(fileName);
private static void equals(
TreeMap<String, ByteArrayOutputStream> file1,
TreeMap<String, ByteArrayOutputStream> file2) {
Set<String> listFile1 = file1.keySet();
Assert.assertEquals("not the same number of files in zip:", listFile1.size(), file2.keySet().size());
assertNotNull(fileName + " not found in 2nd zip", contain2);
// no need to check for contain1. The key come from it
for (String fileName : listFile1) {
// extract the contents for both
ByteArrayOutputStream contain1 = file1.get(fileName);
ByteArrayOutputStream contain2 = file2.get(fileName);
if (fileName.matches(".*\\.(xml|rels)$")) {
// we have a xml file
final Diff diff = DiffBuilder.
compare(Input.fromByteArray(contain1.toByteArray())).
withTest(Input.fromByteArray(contain2.toByteArray())).
ignoreWhitespace().
checkForSimilar().
withDifferenceEvaluator(new IgnoreXMLDeclEvaluator()).
withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndAllAttributes, ElementSelectors.byNameAndText)).
build();
assertFalse(fileName+": "+diff.toString(), diff.hasDifferences());
assertNotNull(fileName + " not found in 2nd zip", contain2);
// no need to check for contain1. The key come from it
if (fileName.matches(".*\\.(xml|rels)$")) {
// we have a xml file
final Diff diff = DiffBuilder.
compare(Input.fromByteArray(contain1.toByteArray())).
withTest(Input.fromByteArray(contain2.toByteArray())).
ignoreWhitespace().
checkForSimilar().
withDifferenceEvaluator(new IgnoreXMLDeclEvaluator()).
withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndAllAttributes, ElementSelectors.byNameAndText)).
build();
assertFalse(fileName+": "+diff.toString(), diff.hasDifferences());
} else {
// not xml, may be an image or other binary format
// not xml, may be an image or other binary format
Assert.assertEquals(fileName + " does not have the same size in both zip:", contain1.size(), contain2.size());
assertArrayEquals("contents differ", contain1.toByteArray(), contain2.toByteArray());
}
}
}
assertArrayEquals("contents differ", contain1.toByteArray(), contain2.toByteArray());
}
}
}
private static TreeMap<String, ByteArrayOutputStream> decompress(
File filename) throws IOException {
// store the zip content in memory
// let s assume it is not Go ;-)
TreeMap<String, ByteArrayOutputStream> zipContent = new TreeMap<>();
private static TreeMap<String, ByteArrayOutputStream> decompress(
File filename) throws IOException {
// store the zip content in memory
// let s assume it is not Go ;-)
TreeMap<String, ByteArrayOutputStream> zipContent = new TreeMap<>();
/* Open file to decompress */
FileInputStream file_decompress = new FileInputStream(filename);
try (
/* Open file to decompress */
FileInputStream file_decompress = new FileInputStream(filename);
/* Create a buffer for the decompressed files */
BufferedInputStream buffi = new BufferedInputStream(file_decompress);
/* Create a buffer for the decompressed files */
BufferedInputStream buffi = new BufferedInputStream(file_decompress);
/* Open the file with the buffer */
ZipArchiveInputStream zis = new ZipArchiveInputStream(buffi);
/* Open the file with the buffer */
ZipArchiveInputStream zis = new ZipArchiveInputStream(buffi);
) {
/* Processing entries of the zip file */
ArchiveEntry entree;
while ((entree = zis.getNextEntry()) != null) {
/* Processing entries of the zip file */
ArchiveEntry entree;
while ((entree = zis.getNextEntry()) != null) {
/* Create a array for the current entry */
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
IOUtils.copy(zis, byteArray);
zipContent.put(entree.getName(), byteArray);
}
/* Create a array for the current entry */
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
IOUtils.copy(zis, byteArray);
zipContent.put(entree.getName(), byteArray);
}
zis.close();
}
return zipContent;
}
return zipContent;
}
/**
* Asserts that two files are equal. Throws an <tt>AssertionFailedError</tt>
* if they are not.
* <p>
*
*/
public static void assertEquals(File expected, File actual) {
assertNotNull(expected);
assertNotNull(actual);
/**
* Asserts that two files are equal. Throws an <tt>AssertionFailedError</tt>
* if they are not.
* <p>
*
*/
public static void assertEquals(File expected, File actual) {
assertNotNull(expected);
assertNotNull(actual);
assertTrue("File does not exist [" + expected.getAbsolutePath()
+ "]", expected.exists());
assertTrue("File does not exist [" + actual.getAbsolutePath()
+ "]", actual.exists());
assertTrue("File does not exist [" + expected.getAbsolutePath()
+ "]", expected.exists());
assertTrue("File does not exist [" + actual.getAbsolutePath()
+ "]", actual.exists());
assertTrue("Expected file not readable", expected.canRead());
assertTrue("Actual file not readable", actual.canRead());
assertTrue("Expected file not readable", expected.canRead());
assertTrue("Actual file not readable", actual.canRead());
try {
TreeMap<String, ByteArrayOutputStream> file1 = decompress(expected);
TreeMap<String, ByteArrayOutputStream> file2 = decompress(actual);
equals(file1, file2);
} catch (IOException e) {
throw new AssertionFailedError(e.toString());
}
}
try {
TreeMap<String, ByteArrayOutputStream> file1 = decompress(expected);
TreeMap<String, ByteArrayOutputStream> file2 = decompress(actual);
equals(file1, file2);
} catch (IOException e) {
throw new AssertionFailedError(e.toString());
}
}
private static class IgnoreXMLDeclEvaluator implements DifferenceEvaluator {
public ComparisonResult evaluate(final Comparison comparison, final ComparisonResult outcome) {
if (outcome != ComparisonResult.EQUAL) {
// only evaluate differences
switch (comparison.getType()) {
case CHILD_NODELIST_SEQUENCE:
case XML_STANDALONE:
case NAMESPACE_PREFIX:
return ComparisonResult.SIMILAR;
case TEXT_VALUE:
switch (comparison.getControlDetails().getTarget().getParentNode().getNodeName()) {
case "dcterms:created":
case "dc:creator":
return ComparisonResult.SIMILAR;
}
break;
default:
break;
}
}
private static class IgnoreXMLDeclEvaluator implements DifferenceEvaluator {
@Override
public ComparisonResult evaluate(final Comparison comparison, final ComparisonResult outcome) {
if (outcome != ComparisonResult.EQUAL) {
// only evaluate differences
switch (comparison.getType()) {
case CHILD_NODELIST_SEQUENCE:
case XML_STANDALONE:
case NAMESPACE_PREFIX:
return ComparisonResult.SIMILAR;
case TEXT_VALUE:
switch (comparison.getControlDetails().getTarget().getParentNode().getNodeName()) {
case "dcterms:created":
case "dc:creator":
return ComparisonResult.SIMILAR;
}
break;
default:
break;
}
}
return outcome;
}
}
return outcome;
}
}
}

View File

@ -83,9 +83,7 @@ public final class TestOPCComplianceCoreProperties {
try {
InputStream is = OpenXML4JTestDataSamples.openComplianceSampleStream("OPCCompliance_CoreProperties_OnlyOneCorePropertiesPart.docx");
pkg = OPCPackage.open(is);
} catch (InvalidFormatException e) {
throw new RuntimeException(e);
} catch (IOException e) {
} catch (InvalidFormatException | IOException e) {
throw new RuntimeException(e);
}
pkg.revert();
@ -151,9 +149,7 @@ public final class TestOPCComplianceCoreProperties {
OPCPackage pkg;
try {
pkg = OPCPackage.open(is);
} catch (InvalidFormatException e) {
throw new RuntimeException(e);
} catch (IOException e) {
} catch (InvalidFormatException | IOException e) {
throw new RuntimeException(e);
}
URI partUri = createURI("/docProps/core2.xml");

View File

@ -74,7 +74,7 @@ public class TestFonts {
// currently linux and mac return quite different values
private static final int[] expected_sizes = {
304, // windows 10, 1080p, MS Office 2016, system text scaling 100% instead of default 125%
306, // Windows 10, 15.6" 3840x2160
306, 308,// Windows 10, 15.6" 3840x2160
311, 312, 313, 318,
348, // Windows 10, 15.6" 3840x2160
362, // Windows 10, 13.3" 1080p high-dpi

View File

@ -17,18 +17,25 @@
package org.apache.poi.ss;
import static org.junit.Assert.*;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileNotFoundException;
import org.apache.poi.EmptyFileException;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
@ -36,16 +43,14 @@ import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.TempFile;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.xssf.usermodel.XSSFWorkbookFactory;
import org.junit.Test;
public final class TestWorkbookFactory {
private static final String xls = "SampleSS.xls";
private static final String xlsx = "SampleSS.xlsx";
private static final String[] xls_prot = new String[] {"password.xls", "password"};
private static final String[] xlsx_prot = new String[]{"protected_passtika.xlsx", "tika"};
private static final String[] xls_protected = new String[] {"password.xls", "password"};
private static final String[] xlsx_protected = new String[]{"protected_passtika.xlsx", "tika"};
private static final String txt = "SampleSS.txt";
private static final POILogger LOGGER = POILogFactory.getLogger(TestWorkbookFactory.class);
@ -105,6 +110,13 @@ public final class TestWorkbookFactory {
assertTrue(wb instanceof HSSFWorkbook);
assertCloseDoesNotModifyFile(xls, wb);
wb = WorkbookFactory.create(
new POIFSFileSystem(HSSFTestDataSamples.openSampleFileStream(xls)).getRoot()
);
assertNotNull(wb);
assertTrue(wb instanceof HSSFWorkbook);
assertCloseDoesNotModifyFile(xls, wb);
// Package -> xssf
wb = XSSFWorkbookFactory.create(
OPCPackage.open(
@ -195,7 +207,6 @@ public final class TestWorkbookFactory {
public void testCreateWithPasswordFromStream() throws Exception {
Workbook wb;
// Unprotected, no password given, opens normally
wb = WorkbookFactory.create(
HSSFTestDataSamples.openSampleFileStream(xls), null
@ -230,26 +241,26 @@ public final class TestWorkbookFactory {
// Protected, correct password, opens fine
wb = WorkbookFactory.create(
HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), xls_prot[1]
HSSFTestDataSamples.openSampleFileStream(xls_protected[0]), xls_protected[1]
);
assertNotNull(wb);
assertTrue(wb instanceof HSSFWorkbook);
assertCloseDoesNotModifyFile(xls_prot[0], wb);
assertCloseDoesNotModifyFile(xls_protected[0], wb);
wb = WorkbookFactory.create(
HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), xlsx_prot[1]
HSSFTestDataSamples.openSampleFileStream(xlsx_protected[0]), xlsx_protected[1]
);
assertNotNull(wb);
assertTrue(wb instanceof XSSFWorkbook);
assertCloseDoesNotModifyFile(xlsx_prot[0], wb);
assertCloseDoesNotModifyFile(xlsx_protected[0], wb);
// Protected, wrong password, throws Exception
try {
wb = WorkbookFactory.create(
HSSFTestDataSamples.openSampleFileStream(xls_prot[0]), "wrong"
HSSFTestDataSamples.openSampleFileStream(xls_protected[0]), "wrong"
);
assertCloseDoesNotModifyFile(xls_prot[0], wb);
assertCloseDoesNotModifyFile(xls_protected[0], wb);
fail("Shouldn't be able to open with the wrong password");
} catch (EncryptedDocumentException e) {
// expected here
@ -257,9 +268,9 @@ public final class TestWorkbookFactory {
try {
wb = WorkbookFactory.create(
HSSFTestDataSamples.openSampleFileStream(xlsx_prot[0]), "wrong"
HSSFTestDataSamples.openSampleFileStream(xlsx_protected[0]), "wrong"
);
assertCloseDoesNotModifyFile(xlsx_prot[0], wb);
assertCloseDoesNotModifyFile(xlsx_protected[0], wb);
fail("Shouldn't be able to open with the wrong password");
} catch (EncryptedDocumentException e) {
// expected here
@ -305,28 +316,28 @@ public final class TestWorkbookFactory {
// Protected, correct password, opens fine
wb = WorkbookFactory.create(
HSSFTestDataSamples.getSampleFile(xls_prot[0]), xls_prot[1]
HSSFTestDataSamples.getSampleFile(xls_protected[0]), xls_protected[1]
);
assertNotNull(wb);
assertTrue(wb instanceof HSSFWorkbook);
assertCloseDoesNotModifyFile(xls_prot[0], wb);
assertCloseDoesNotModifyFile(xls_protected[0], wb);
wb = WorkbookFactory.create(
HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), xlsx_prot[1]
HSSFTestDataSamples.getSampleFile(xlsx_protected[0]), xlsx_protected[1]
);
assertNotNull(wb);
assertTrue(wb instanceof XSSFWorkbook);
assertTrue(wb.getNumberOfSheets() > 0);
assertNotNull(wb.getSheetAt(0));
assertNotNull(wb.getSheetAt(0).getRow(0));
assertCloseDoesNotModifyFile(xlsx_prot[0], wb);
assertCloseDoesNotModifyFile(xlsx_protected[0], wb);
// Protected, wrong password, throws Exception
try {
wb = WorkbookFactory.create(
HSSFTestDataSamples.getSampleFile(xls_prot[0]), "wrong"
HSSFTestDataSamples.getSampleFile(xls_protected[0]), "wrong"
);
assertCloseDoesNotModifyFile(xls_prot[0], wb);
assertCloseDoesNotModifyFile(xls_protected[0], wb);
fail("Shouldn't be able to open with the wrong password");
} catch (EncryptedDocumentException e) {
// expected here
@ -334,9 +345,9 @@ public final class TestWorkbookFactory {
try {
wb = WorkbookFactory.create(
HSSFTestDataSamples.getSampleFile(xlsx_prot[0]), "wrong"
HSSFTestDataSamples.getSampleFile(xlsx_protected[0]), "wrong"
);
assertCloseDoesNotModifyFile(xlsx_prot[0], wb);
assertCloseDoesNotModifyFile(xlsx_protected[0], wb);
fail("Shouldn't be able to open with the wrong password");
} catch (EncryptedDocumentException e) {
// expected here
@ -387,4 +398,59 @@ public final class TestWorkbookFactory {
}
}
/**
* See Bugzilla bug #62831 - #WorkbookFactory.create(File) needs
* to work for sub-classes of File too, eg JFileChooser
*/
@Test
public void testFileSubclass() throws Exception {
File normalXLS = HSSFTestDataSamples.getSampleFile(xls);
File normalXLSX = HSSFTestDataSamples.getSampleFile(xlsx);
File altXLS = new TestFile(normalXLS.getAbsolutePath());
File altXLSX = new TestFile(normalXLSX.getAbsolutePath());
assertTrue(altXLS.exists());
assertTrue(altXLSX.exists());
Workbook wb = WorkbookFactory.create(altXLS);
assertNotNull(wb);
assertTrue(wb instanceof HSSFWorkbook);
closeOrRevert(wb);
wb = WorkbookFactory.create(altXLSX);
assertNotNull(wb);
assertTrue(wb instanceof XSSFWorkbook);
closeOrRevert(wb);
}
private static class TestFile extends File {
public TestFile(String file) {
super(file);
}
}
/**
* Check that the overloaded file methods which take passwords work properly
*/
@Test
public void testCreateEmpty() throws Exception {
Workbook wb = WorkbookFactory.create(false);
assertTrue(wb instanceof HSSFWorkbook);
closeOrRevert(wb);
wb = WorkbookFactory.create(true);
assertTrue(wb instanceof XSSFWorkbook);
closeOrRevert(wb);
}
@Test
public void testInvalidFormatException() {
String filename = "OPCCompliance_DerivedPartNameFAIL.docx";
try {
WorkbookFactory.create(POIDataSamples.getOpenXML4JInstance().openResourceAsStream(filename));
fail("Expecting an Exception for this document");
} catch (IOException e) {
// expected here
}
}
}

View File

@ -47,22 +47,22 @@ public class TestXSLFTextParagraph {
DrawTextParagraphProxy(XSLFTextParagraph p) {
super(p);
}
@Override
public void breakText(Graphics2D graphics) {
super.breakText(graphics);
}
@Override
public double getWrappingWidth(boolean firstLine, Graphics2D graphics) {
return super.getWrappingWidth(firstLine, graphics);
}
public List<DrawTextFragment> getLines() {
return lines;
}
}
@Test
public void testWrappingWidth() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
@ -78,11 +78,11 @@ public class TestXSLFTextParagraph {
Rectangle2D anchor = new Rectangle2D.Double(50, 50, 300, 200);
sh.setAnchor(anchor);
DrawTextParagraphProxy dtp = new DrawTextParagraphProxy(p);
Double leftInset = sh.getLeftInset();
Double rightInset = sh.getRightInset();
double leftInset = sh.getLeftInset();
double rightInset = sh.getRightInset();
assertEquals(7.2, leftInset, 0);
assertEquals(7.2, rightInset, 0);
@ -142,13 +142,13 @@ public class TestXSLFTextParagraph {
indent = p.getIndent();
assertEquals(-72.0, indent, 0);
expectedWidth = anchor.getWidth() - leftInset - rightInset;
assertEquals(280.0, expectedWidth, 0); // 300 - 10 - 10
assertEquals(280.0, expectedWidth, 0); // 300 - 10 - 10
assertEquals(expectedWidth, dtp.getWrappingWidth(true, null), 0); // first line is NOT indented
// other lines are indented by leftMargin (the value of indent is not used)
expectedWidth = anchor.getWidth() - leftInset - rightInset - leftMargin;
assertEquals(244.0, expectedWidth, 0); // 300 - 10 - 10 - 36
assertEquals(244.0, expectedWidth, 0); // 300 - 10 - 10 - 36
assertEquals(expectedWidth, dtp.getWrappingWidth(false, null), 0);
ppt.close();
}
@ -294,13 +294,13 @@ public class TestXSLFTextParagraph {
assertEquals(-20.0, p.getBulletFontSize(), 0);
assertEquals(72.0, p.getDefaultTabSize(), 0);
assertNull(p.getIndent());
p.setIndent(72.0);
assertEquals(72.0, p.getIndent(), 0);
p.setIndent(-1d); // the value of -1.0 resets to the defaults (not any more ...)
assertEquals(-1d, p.getIndent(), 0);
p.setIndent(null);
p.setIndent(null);
assertNull(p.getIndent());
assertEquals(0.0, p.getLeftMargin(), 0);

View File

@ -28,13 +28,12 @@ import java.io.InputStream;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.TempFile;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* Centralises logic for finding/opening sample files in the test-data/spreadsheet folder.
*
* Centralises logic for finding/opening sample files in the test-data/spreadsheet folder.
*
* @author Josh Micich
*/
public class XSSFTestDataSamples {
@ -63,7 +62,7 @@ public class XSSFTestDataSamples {
throw new RuntimeException(e);
}
}
/**
* Write out workbook <code>wb</code> to {@link #TEST_OUTPUT_DIR}/testName.xlsx
* (or create a temporary file if <code>TEST_OUTPUT_DIR</code> is not defined).
@ -78,11 +77,13 @@ public class XSSFTestDataSamples {
writeOut(wb, file);
return file;
}
private static <R extends Workbook> void writeOut(R wb, File file) throws IOException {
IOUtils.write(wb, new FileOutputStream(file));
try (FileOutputStream out = new FileOutputStream(file)) {
wb.write(out);
}
}
// Anticipates the location of where a workbook will be written to
// Note that if TEST_OUTPUT_DIR is not set, this will create temporary files
// with unique names. Subsequent calls with the same argument may return a different file.
@ -107,7 +108,7 @@ public class XSSFTestDataSamples {
}
return file;
}
/**
* Write out workbook <code>wb</code> to a memory buffer
*
@ -120,18 +121,18 @@ public class XSSFTestDataSamples {
wb.write(out);
return out;
}
/**
* Write out the workbook then closes the workbook.
* Write out the workbook then closes the workbook.
* This should be used when there is insufficient memory to have
* both workbooks open.
*
*
* Make sure there are no references to any objects in the workbook
* so that garbage collection may free the workbook.
*
*
* After calling this method, null the reference to <code>wb</code>,
* then call {@link #readBack(File)} or {@link #readBackAndDelete(File)} to re-read the file.
*
*
* Alternatively, use {@link #writeOutAndClose(Workbook)} to use a ByteArrayOutputStream/ByteArrayInputStream
* to avoid creating a temporary file. However, this may complicate the calling
* code to avoid having the workbook, BAOS, and BAIS open at the same time.
@ -152,8 +153,8 @@ public class XSSFTestDataSamples {
throw new RuntimeException(e);
}
}
/**
* Write out workbook <code>wb</code> to a memory buffer,
* then close the workbook
@ -173,7 +174,7 @@ public class XSSFTestDataSamples {
throw new RuntimeException(e);
}
}
/**
* Read back a workbook that was written out to a file with
* {@link #writeOut(Workbook, String))} or {@link #writeOutAndClose(Workbook, String)}.
@ -186,11 +187,11 @@ public class XSSFTestDataSamples {
*/
public static XSSFWorkbook readBackAndDelete(File file) throws IOException {
XSSFWorkbook wb = readBack(file);
// do not delete the file if there's an error--might be helpful for debugging
// do not delete the file if there's an error--might be helpful for debugging
file.delete();
return wb;
}
/**
* Read back a workbook that was written out to a file with
* {@link #writeOut(Workbook, String)} or {@link #writeOutAndClose(Workbook, String)}.
@ -208,12 +209,12 @@ public class XSSFTestDataSamples {
in.close();
}
}
/**
* Read back a workbook that was written out to a memory buffer with
* {@link #writeOut(Workbook)} or {@link #writeOutAndClose(Workbook)}.
*
* @param file the workbook file to read
* @param out the output stream to read back from
* @return the read back workbook
* @throws IOException
*/
@ -227,15 +228,15 @@ public class XSSFTestDataSamples {
is.close();
}
}
/**
* Write out and read back using a memory buffer to avoid disk I/O.
* If there is not enough memory to have two workbooks open at the same time,
* consider using:
*
*
* Workbook wb = new XSSFWorkbook();
* String testName = "example";
*
*
* <code>
* File file = writeOutAndClose(wb, testName);
* // clear all references that would prevent the workbook from getting garbage collected
@ -257,7 +258,7 @@ public class XSSFTestDataSamples {
R r = (R) result;
return r;
}
/**
* Write out, close, and read back the workbook using a memory buffer to avoid disk I/O.
*
@ -274,18 +275,18 @@ public class XSSFTestDataSamples {
@SuppressWarnings("unchecked")
R r = (R) result;
return r;
}
/**
* Writes the Workbook either into a file or into a byte array, depending on presence of
* Writes the Workbook either into a file or into a byte array, depending on presence of
* the system property {@value #TEST_OUTPUT_DIR}, and reads it in a new instance of the Workbook back.
* If TEST_OUTPUT_DIR is set, the file will NOT be deleted at the end of this function.
* @param wb workbook to write
* @param testName file name to be used if writing into a file. The old file with the same name will be overridden.
* @return new instance read from the stream written by the wb parameter.
*/
public static <R extends Workbook> R writeOutAndReadBack(R wb, String testName) {
if (System.getProperty(TEST_OUTPUT_DIR) == null) {
return writeOutAndReadBack(wb);

View File

@ -26,6 +26,10 @@ import static org.junit.Assert.assertTrue;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.junit.Test;
import java.io.BufferedReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
/**
* Tests for {@link XSSFBEventBasedExcelExtractor}
*/
@ -110,4 +114,23 @@ public class TestXSSFBEventBasedExcelExtractor {
"This is an example spreadsheet created with Microsoft Excel 2007 Beta 2.");
}
@Test
public void test62815() throws Exception {
//test file based on http://oss.sheetjs.com/test_files/RkNumber.xlsb
XSSFEventBasedExcelExtractor extractor = getExtractor("62815.xlsb");
extractor.setIncludeCellComments(true);
String[] rows = extractor.getText().split("[\r\n]+");
assertEquals(283, rows.length);
BufferedReader reader = Files.newBufferedReader(XSSFTestDataSamples.getSampleFile("62815.xlsb.txt").toPath(),
StandardCharsets.UTF_8);
String line = reader.readLine();
for (int i = 0; i < rows.length; i++) {
assertEquals(line, rows[i]);
line = reader.readLine();
while (line != null && line.startsWith("#")) {
line = reader.readLine();
}
}
}
}

View File

@ -38,7 +38,6 @@ import java.util.Arrays;
import org.apache.poi.POIDataSamples;
import org.apache.poi.POITestCase;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.ss.usermodel.BaseTestXWorkbook;
@ -55,7 +54,6 @@ import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.After;
import org.junit.Assume;
import org.junit.Ignore;
import org.junit.Test;
@ -103,9 +101,9 @@ public final class TestSXSSFWorkbook extends BaseTestXWorkbook {
* changes.
*/
@Override
@Ignore("SXSSF doesn't update formulas on sheet name changes, as most cells probably aren't in memory at the time")
@Test
public void setSheetName() {
Assume.assumeTrue("SXSSF doesn't update formulas on sheet name changes, as most cells probably aren't in memory at the time", false);
}
@Test
@ -374,7 +372,7 @@ public final class TestSXSSFWorkbook extends BaseTestXWorkbook {
@Test
public void bug53515a() throws Exception {
File out = new File("Test.xlsx");
out.delete();
assertTrue(!out.exists() || out.delete());
for (int i = 0; i < 2; i++) {
final SXSSFWorkbook wb;
if (out.exists()) {
@ -402,7 +400,8 @@ public final class TestSXSSFWorkbook extends BaseTestXWorkbook {
}
wb.close();
}
out.delete();
assertTrue(out.exists());
assertTrue(out.delete());
}
private static void populateWorkbook(Workbook wb) {
@ -500,33 +499,37 @@ public final class TestSXSSFWorkbook extends BaseTestXWorkbook {
@Test
@Ignore
public void createFromReadOnlyWorkbook() throws Exception {
File input = XSSFTestDataSamples.getSampleFile("sample.xlsx");
OPCPackage pkg = OPCPackage.open(input, PackageAccess.READ);
XSSFWorkbook xssf = new XSSFWorkbook(pkg);
SXSSFWorkbook wb = new SXSSFWorkbook(xssf, 2);
String sheetName = "Test SXSSF";
Sheet s = wb.createSheet(sheetName);
for (int i=0; i<10; i++) {
Row r = s.createRow(i);
r.createCell(0).setCellValue(true);
r.createCell(1).setCellValue(2.4);
r.createCell(2).setCellValue("Test Row " + i);
File input = XSSFTestDataSamples.getSampleFile("sample.xlsx");
try (OPCPackage pkg = OPCPackage.open(input, PackageAccess.READ)) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (XSSFWorkbook xssf = new XSSFWorkbook(pkg)) {
try (SXSSFWorkbook wb = new SXSSFWorkbook(xssf, 2)) {
Sheet s = wb.createSheet(sheetName);
for (int i = 0; i < 10; i++) {
Row r = s.createRow(i);
r.createCell(0).setCellValue(true);
r.createCell(1).setCellValue(2.4);
r.createCell(2).setCellValue("Test Row " + i);
}
assertEquals(10, s.getLastRowNum());
wb.write(bos);
wb.dispose();
}
}
try (XSSFWorkbook xssf = new XSSFWorkbook(new ByteArrayInputStream(bos.toByteArray()))) {
Sheet s = xssf.getSheet(sheetName);
assertEquals(10, s.getLastRowNum());
assertTrue(s.getRow(0).getCell(0).getBooleanCellValue());
assertEquals("Test Row 9", s.getRow(9).getCell(2).getStringCellValue());
}
}
assertEquals(10, s.getLastRowNum());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
wb.write(bos);
wb.dispose();
wb.close();
xssf = new XSSFWorkbook(new ByteArrayInputStream(bos.toByteArray()));
s = xssf.getSheet(sheetName);
assertEquals(10, s.getLastRowNum());
assertTrue(s.getRow(0).getCell(0).getBooleanCellValue());
assertEquals("Test Row 9", s.getRow(9).getCell(2).getStringCellValue());
}
@Test
public void test56557() throws IOException {
Workbook wb = XSSFTestDataSamples.openSampleWorkbook("56557.xlsx");

View File

@ -47,15 +47,15 @@ import java.util.TreeMap;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.poi.POIDataSamples;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.hssf.HSSFITestDataProvider;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
@ -82,7 +82,31 @@ import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.functions.Function;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.FormulaError;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.PrintSetup;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellRangeAddress;
@ -2261,7 +2285,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
* problems when deleting columns, conditionally to stop recursion
*/
private static final String FORMULA1 =
"IF( INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) = 0, 0,"
"IF( INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) = 0, 0, "
+ "INDIRECT( ADDRESS( ROW(), COLUMN()-1 ) ) ) + 2";
/**
@ -2269,7 +2293,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
* problems when deleting rows, conditionally to stop recursion
*/
private static final String FORMULA2 =
"IF( INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) = 0, 0,"
"IF( INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) = 0, 0, "
+ "INDIRECT( ADDRESS( ROW()-1, COLUMN() ) ) ) + 2";
/**
@ -2847,7 +2871,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
@Test
public void test57236() throws IOException {
// Having very small numbers leads to different formatting, Excel uses the scientific notation, but POI leads to "0"
/*
DecimalFormat format = new DecimalFormat("#.##########", new DecimalFormatSymbols(Locale.getDefault()));
double d = 3.0E-104;
@ -2969,13 +2993,21 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
cell.setCellStyle(style);
// Everything is fine at this point, cell is red
XSSFColor actual = cell.getCellStyle().getFillBackgroundColorColor();
assertNull(actual);
actual = cell.getCellStyle().getFillForegroundColorColor();
assertNotNull(actual);
assertEquals(color.getARGBHex(), actual.getARGBHex());
Map<String, Object> properties = new HashMap<>();
properties.put(CellUtil.BORDER_BOTTOM, BorderStyle.THIN);
CellUtil.setCellStyleProperties(cell, properties);
// Now the cell is all black
XSSFColor actual = cell.getCellStyle().getFillBackgroundColorColor();
actual = cell.getCellStyle().getFillBackgroundColorColor();
assertNotNull(actual);
assertNull(actual.getARGBHex());
actual = cell.getCellStyle().getFillForegroundColorColor();
assertNotNull(actual);
assertEquals(color.getARGBHex(), actual.getARGBHex());
@ -3290,7 +3322,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
wb.close();
}
/**
* Auto column sizing failed when there were loads of fonts with
* errors like ArrayIndexOutOfBoundsException: -32765
@ -3300,7 +3332,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
XSSFRow row = sheet.createRow(0);
// Create lots of fonts
XSSFDataFormat formats = wb.createDataFormat();
XSSFFont[] fonts = new XSSFFont[50000];
@ -3309,23 +3341,23 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
font.setFontHeight(i);
fonts[i] = font;
}
// Create a moderate number of columns, which use
// fonts from the start and end of the font list
final int numCols = 125;
for (int i=0; i<numCols; i++) {
XSSFCellStyle cs = wb.createCellStyle();
cs.setDataFormat(formats.getFormat("'Test "+i+"' #,###"));
XSSFFont font = fonts[i];
if (i%2==1) { font = fonts[fonts.length-i]; }
cs.setFont(font);
XSSFCell c = row.createCell(i);
c.setCellValue(i);
c.setCellStyle(cs);
}
// Do the auto-size
for (int i=0; i<numCols; i++) {
sheet.autoSizeColumn(i);

View File

@ -33,20 +33,20 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
* Test asserts the POI produces &lt;cols&gt; element that could be read and properly interpreted by the MS Excel.
* For specification of the "cols" element see the chapter 3.3.1.16 of the "Office Open XML Part 4 - Markup Language Reference.pdf".
* The specification can be downloaded at http://www.ecma-international.org/publications/files/ECMA-ST/Office%20Open%20XML%201st%20edition%20Part%204%20(PDF).zip.
*
*
* <p><em>
* The test saves xlsx file on a disk if the system property is set:
* -Dpoi.test.xssf.output.dir=${workspace_loc}/poi/build/xssf-output
* </em>
*
*
*/
public class TestXSSFColGrouping {
private static final POILogger logger = POILogFactory.getLogger(TestXSSFColGrouping.class);
/**
* Tests that POI doesn't produce "col" elements without "width" attribute.
* Tests that POI doesn't produce "col" elements without "width" attribute.
* POI-52186
*/
@Test
@ -56,25 +56,25 @@ public class TestXSSFColGrouping {
sheet.setColumnWidth(4, 5000);
sheet.setColumnWidth(5, 5000);
sheet.groupColumn((short) 4, (short) 7);
sheet.groupColumn((short) 9, (short) 12);
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testNoColsWithoutWidthWhenGrouping");
sheet = wb2.getSheet("test");
CTCols cols = sheet.getCTWorksheet().getColsArray(0);
logger.log(POILogger.DEBUG, "test52186/cols:" + cols);
for (CTCol col : cols.getColArray()) {
assertTrue("Col width attribute is unset: " + col, col.isSetWidth());
}
wb2.close();
wb1.close();
}
/**
* Tests that POI doesn't produce "col" elements without "width" attribute.
* Tests that POI doesn't produce "col" elements without "width" attribute.
* POI-52186
*/
@Test
@ -84,17 +84,17 @@ public class TestXSSFColGrouping {
sheet.setColumnWidth(4, 5000);
sheet.setColumnWidth(5, 5000);
sheet.groupColumn((short) 4, (short) 5);
sheet.setColumnGroupCollapsed(4, true);
CTCols cols = sheet.getCTWorksheet().getColsArray(0);
logger.log(POILogger.DEBUG, "test52186_2/cols:" + cols);
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testNoColsWithoutWidthWhenGroupingAndCollapsing");
sheet = wb2.getSheet("test");
for (int i = 4; i <= 5; i++) {
assertEquals("Unexpected width of column "+ i, 5000, sheet.getColumnWidth(i));
}
@ -105,7 +105,7 @@ public class TestXSSFColGrouping {
wb2.close();
wb1.close();
}
/**
* Test the cols element is correct in case of NumericRanges.OVERLAPS_2_WRAPS
*/
@ -122,10 +122,10 @@ public class TestXSSFColGrouping {
col.setCustomWidth(true);
sheet.groupColumn((short) 2, (short) 3);
sheet.getCTWorksheet().getColsArray(0);
logger.log(POILogger.DEBUG, "testMergingOverlappingCols_OVERLAPS_2_WRAPS/cols:" + cols);
assertEquals(0, cols.getColArray(0).getOutlineLevel());
assertEquals(2, cols.getColArray(0).getMin()); // 1 based
assertEquals(2, cols.getColArray(0).getMax()); // 1 based
@ -133,23 +133,23 @@ public class TestXSSFColGrouping {
assertEquals(1, cols.getColArray(1).getOutlineLevel());
assertEquals(3, cols.getColArray(1).getMin()); // 1 based
assertEquals(4, cols.getColArray(1).getMax()); // 1 based
assertEquals(4, cols.getColArray(1).getMax()); // 1 based
assertEquals(true, cols.getColArray(1).getCustomWidth());
assertEquals(0, cols.getColArray(2).getOutlineLevel());
assertEquals(5, cols.getColArray(2).getMin()); // 1 based
assertEquals(5, cols.getColArray(2).getMax()); // 1 based
assertEquals(true, cols.getColArray(2).getCustomWidth());
assertEquals(3, cols.sizeOfColArray());
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_2_WRAPS");
sheet = wb2.getSheet("test");
for (int i = 1; i <= 4; i++) {
assertEquals("Unexpected width of column "+ i, 20 * 256, sheet.getColumnWidth(i));
}
wb2.close();
wb1.close();
}
@ -170,10 +170,10 @@ public class TestXSSFColGrouping {
col.setCustomWidth(true);
sheet.groupColumn((short) 1, (short) 5);
cols = sheet.getCTWorksheet().getColsArray(0);
logger.log(POILogger.DEBUG, "testMergingOverlappingCols_OVERLAPS_1_WRAPS/cols:" + cols);
assertEquals(1, cols.getColArray(0).getOutlineLevel());
assertEquals(2, cols.getColArray(0).getMin()); // 1 based
assertEquals(2, cols.getColArray(0).getMax()); // 1 based
@ -181,23 +181,23 @@ public class TestXSSFColGrouping {
assertEquals(1, cols.getColArray(1).getOutlineLevel());
assertEquals(3, cols.getColArray(1).getMin()); // 1 based
assertEquals(5, cols.getColArray(1).getMax()); // 1 based
assertEquals(5, cols.getColArray(1).getMax()); // 1 based
assertEquals(true, cols.getColArray(1).getCustomWidth());
assertEquals(1, cols.getColArray(2).getOutlineLevel());
assertEquals(6, cols.getColArray(2).getMin()); // 1 based
assertEquals(6, cols.getColArray(2).getMax()); // 1 based
assertEquals(false, cols.getColArray(2).getCustomWidth());
assertEquals(3, cols.sizeOfColArray());
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_1_WRAPS");
sheet = wb2.getSheet("test");
for (int i = 2; i <= 4; i++) {
assertEquals("Unexpected width of column "+ i, 20 * 256, sheet.getColumnWidth(i));
}
wb2.close();
wb1.close();
}
@ -218,7 +218,7 @@ public class TestXSSFColGrouping {
col.setCustomWidth(true);
sheet.groupColumn((short) 3, (short) 5);
cols = sheet.getCTWorksheet().getColsArray(0);
logger.log(POILogger.DEBUG, "testMergingOverlappingCols_OVERLAPS_1_MINOR/cols:" + cols);
@ -229,24 +229,24 @@ public class TestXSSFColGrouping {
assertEquals(1, cols.getColArray(1).getOutlineLevel());
assertEquals(4, cols.getColArray(1).getMin()); // 1 based
assertEquals(5, cols.getColArray(1).getMax()); // 1 based
assertEquals(5, cols.getColArray(1).getMax()); // 1 based
assertEquals(true, cols.getColArray(1).getCustomWidth());
assertEquals(1, cols.getColArray(2).getOutlineLevel());
assertEquals(6, cols.getColArray(2).getMin()); // 1 based
assertEquals(6, cols.getColArray(2).getMax()); // 1 based
assertEquals(false, cols.getColArray(2).getCustomWidth());
assertEquals(3, cols.sizeOfColArray());
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_1_MINOR");
sheet = wb2.getSheet("test");
for (int i = 2; i <= 4; i++) {
assertEquals("Unexpected width of column "+ i, 20 * 256, sheet.getColumnWidth(i));
assertEquals("Unexpected width of column "+ i, 20 * 256L, sheet.getColumnWidth(i));
}
assertEquals("Unexpected width of column "+ 5, sheet.getDefaultColumnWidth() * 256, sheet.getColumnWidth(5));
assertEquals("Unexpected width of column "+ 5, sheet.getDefaultColumnWidth() * 256L, sheet.getColumnWidth(5));
wb2.close();
wb1.close();
}
@ -267,7 +267,7 @@ public class TestXSSFColGrouping {
col.setCustomWidth(true);
sheet.groupColumn((short) 1, (short) 3);
cols = sheet.getCTWorksheet().getColsArray(0);
logger.log(POILogger.DEBUG, "testMergingOverlappingCols_OVERLAPS_2_MINOR/cols:" + cols);
@ -278,24 +278,24 @@ public class TestXSSFColGrouping {
assertEquals(1, cols.getColArray(1).getOutlineLevel());
assertEquals(3, cols.getColArray(1).getMin()); // 1 based
assertEquals(4, cols.getColArray(1).getMax()); // 1 based
assertEquals(4, cols.getColArray(1).getMax()); // 1 based
assertEquals(true, cols.getColArray(1).getCustomWidth());
assertEquals(0, cols.getColArray(2).getOutlineLevel());
assertEquals(5, cols.getColArray(2).getMin()); // 1 based
assertEquals(5, cols.getColArray(2).getMax()); // 1 based
assertEquals(true, cols.getColArray(2).getCustomWidth());
assertEquals(3, cols.sizeOfColArray());
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1, "testMergingOverlappingCols_OVERLAPS_2_MINOR");
sheet = wb2.getSheet("test");
for (int i = 2; i <= 4; i++) {
assertEquals("Unexpected width of column "+ i, 20 * 256, sheet.getColumnWidth(i));
assertEquals("Unexpected width of column "+ i, 20 * 256L, sheet.getColumnWidth(i));
}
assertEquals("Unexpected width of column "+ 1, sheet.getDefaultColumnWidth() * 256, sheet.getColumnWidth(1));
assertEquals("Unexpected width of column "+ 1, sheet.getDefaultColumnWidth() * 256L, sheet.getColumnWidth(1));
wb2.close();
wb1.close();
}

View File

@ -23,7 +23,6 @@ import java.math.BigDecimal;
import java.util.List;
import org.apache.poi.ss.formula.DataValidationEvaluator;
import org.apache.poi.ss.formula.WorkbookEvaluator;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.usermodel.BaseTestDataValidation;
import org.apache.poi.ss.usermodel.Cell;
@ -57,16 +56,16 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
/**
* For each validation type, there are two cells with the same validation. This tests
* application of a single validation definition to multiple cells.
*
*
* For list ( 3 validations for explicit and 3 for formula )
* - one validation that allows blank.
* - one validation that allows blank.
* - one that does not allow blank.
* - one that does not show the drop down arrow.
* = 2
*
*
* For number validations ( integer/decimal and text length ) with 8 different types of operators.
* = 50
*
* = 50
*
* = 52 ( Total )
*/
assertEquals(52,dataValidations.size());
@ -140,7 +139,7 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
cell_10.setCellValue(XSSFDataValidation.operatorTypeMappings.get(operatorType).toString());
Cell cell_11 = row1.createCell(1);
Cell cell_21 = row1.createCell(2);
Cell cell_22 = i==0 && j < 2 ? row2.createCell(2) : null;
Cell cell_22 = i==0 && j < 2 ? (row2 == null ? null : row2.createCell(2)) : null;
Cell cell_13 = row1.createCell(3);
@ -170,7 +169,9 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
assertEquals(++lastKnownNumValidations, ((XSSFSheet) sheet).getDataValidations().size());
cellRangeAddressList = new CellRangeAddressList();
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_22.getRowIndex(), cell_22.getRowIndex(), cell_22.getColumnIndex(), cell_22.getColumnIndex()));
if (cell_22 != null) {
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_22.getRowIndex(), cell_22.getRowIndex(), cell_22.getColumnIndex(), cell_22.getColumnIndex()));
}
validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList);
setOtherValidationParameters( validation);
sheet.addValidationData(validation);
@ -178,7 +179,9 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
} else if(i==0 && j==1 ){
cellRangeAddressList = new CellRangeAddressList();
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_21.getRowIndex(), cell_21.getRowIndex(), cell_21.getColumnIndex(), cell_21.getColumnIndex()));
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_22.getRowIndex(), cell_22.getRowIndex(), cell_22.getColumnIndex(), cell_22.getColumnIndex()));
if (cell_22 != null) {
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_22.getRowIndex(), cell_22.getRowIndex(), cell_22.getColumnIndex(), cell_22.getColumnIndex()));
}
validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList);
setOtherValidationParameters( validation);
sheet.addValidationData(validation);
@ -262,16 +265,16 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
XSSFSheet sheet = wb.createSheet();
List<XSSFDataValidation> lst = sheet.getDataValidations(); //<-- works
assertEquals(0, lst.size());
//create the cell that will have the validation applied
sheet.createRow(0).createCell(0);
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = dataValidationHelper.createCustomConstraint("SUM($A$1:$A$1) <= 3500");
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation validation = dataValidationHelper.createValidation(constraint, addressList);
sheet.addValidationData(validation);
// this line caused XmlValueOutOfRangeException , see Bugzilla 3965
lst = sheet.getDataValidations();
assertEquals(1, lst.size());
@ -282,10 +285,10 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
public void testDefaultErrorStyle() throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet();
final XSSFDataValidation validation = createValidation(sheet);
sheet.addValidationData(validation);
final List<XSSFDataValidation> dataValidations = sheet.getDataValidations();
assertEquals(DataValidation.ErrorStyle.STOP, dataValidations.get(0).getErrorStyle());
}
@ -295,22 +298,22 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
public void testSetErrorStyles() throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet();
XSSFDataValidation validation = createValidation(sheet);
sheet.addValidationData(validation);
// extract generated validation from sheet
List<XSSFDataValidation> dataValidations = sheet.getDataValidations();
validation = dataValidations.get(0);
// test INFO
validation.setErrorStyle(DataValidation.ErrorStyle.INFO);
assertEquals(DataValidation.ErrorStyle.INFO, dataValidations.get(0).getErrorStyle());
// test WARNING
validation.setErrorStyle(DataValidation.ErrorStyle.WARNING);
assertEquals(DataValidation.ErrorStyle.WARNING, dataValidations.get(0).getErrorStyle());
// test STOP
validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
assertEquals(DataValidation.ErrorStyle.STOP, dataValidations.get(0).getErrorStyle());
@ -321,10 +324,10 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
public void testDefaultAllowBlank() throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet();
final XSSFDataValidation validation = createValidation(sheet);
sheet.addValidationData(validation);
final List<XSSFDataValidation> dataValidations = sheet.getDataValidations();
assertEquals(true, dataValidations.get(0).getCtDdataValidation().getAllowBlank());
}
@ -334,12 +337,12 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
public void testSetAllowBlankToFalse() throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet();
final XSSFDataValidation validation = createValidation(sheet);
validation.getCtDdataValidation().setAllowBlank(false);
sheet.addValidationData(validation);
final List<XSSFDataValidation> dataValidations = sheet.getDataValidations();
assertEquals(false, dataValidations.get(0).getCtDdataValidation().getAllowBlank());
}
@ -349,12 +352,12 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
public void testSetAllowBlankToTrue() throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFSheet sheet = wb.createSheet();
final XSSFDataValidation validation = createValidation(sheet);
validation.getCtDdataValidation().setAllowBlank(true);
sheet.addValidationData(validation);
final List<XSSFDataValidation> dataValidations = sheet.getDataValidations();
assertEquals(true, dataValidations.get(0).getCtDdataValidation().getAllowBlank());
}
@ -370,7 +373,7 @@ public class TestXSSFDataValidation extends BaseTestDataValidation {
DataValidationConstraint constraint = dataValidationHelper.createCustomConstraint("true");
return (XSSFDataValidation) dataValidationHelper.createValidation(constraint, new CellRangeAddressList(0, 0, 0, 0));
}
@Test
public void testTableBasedValidationList() throws IOException {
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("dataValidationTableRange.xlsx")) {

View File

@ -17,14 +17,24 @@
package org.apache.poi.xssf.usermodel;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.BaseTestFormulaEvaluator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.XSSFITestDataProvider;
import org.apache.poi.xssf.XSSFTestDataSamples;
@ -437,6 +447,10 @@ public final class TestXSSFFormulaEvaluation extends BaseTestFormulaEvaluator {
assertEquals("D 0,068", evaluator.evaluate(wb.getSheetAt(0).getRow(1).getCell(1)));
}
/**
* see bug 62275
* @throws IOException
*/
@Test
public void testBug62275() throws IOException {
try (Workbook wb = new XSSFWorkbook()) {
@ -451,4 +465,29 @@ public final class TestXSSFFormulaEvaluation extends BaseTestFormulaEvaluator {
eval.evaluate(cell);
}
}
/**
* see bug 62834, handle when a shared formula range doesn't contain only formula cells
* @throws IOException
*/
@Test
public void testBug62834() throws IOException {
try (Workbook wb = XSSFTestDataSamples.openSampleWorkbook("62834.xlsx")) {
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
Cell a2 = wb.getSheetAt(0).getRow(1).getCell(0);
Cell value = evaluator.evaluateInCell(a2);
assertEquals("wrong value A2", "a value", value.getStringCellValue());
// evaluator.clearAllCachedResultValues();
Cell a3 = wb.getSheetAt(0).getRow(2).getCell(0);
value = evaluator.evaluateInCell(a3);
assertEquals("wrong value A3", "a value", value.getStringCellValue());
Cell a5 = wb.getSheetAt(0).getRow(4).getCell(0);
value = evaluator.evaluateInCell(a5);
assertEquals("wrong value A5", "another value", value.getStringCellValue());
}
}
}

View File

@ -36,8 +36,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.poifs.crypt.CryptoFunctions;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.ss.usermodel.AutoFilter;
@ -158,7 +158,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals("", ftr.getLeft());
assertEquals("", ftr.getCenter());
assertEquals("", ftr.getRight());
wb2.close();
}
@ -200,7 +200,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
// Defaults are odd
assertEquals("odd footer left", sheet.getFooter().getLeft());
assertEquals("odd header center", sheet.getHeader().getCenter());
workbook.close();
}
@ -265,7 +265,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
sheet.createSplitPane(4, 8, 12, 12, 1);
assertEquals(8.0, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getYSplit(), 0.0);
assertEquals(STPane.BOTTOM_RIGHT, ctWorksheet.getSheetViews().getSheetViewArray(0).getPane().getActivePane());
workbook.close();
}
@ -374,7 +374,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
colArray = cols.getColArray();
assertEquals(4, colArray.length);
assertEquals(2, sheet.getCTWorksheet().getSheetFormatPr().getOutlineLevelCol());
workbook.close();
}
@ -411,7 +411,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals(3, sheet.getPhysicalNumberOfRows());
assertEquals(1, sheet.getCTWorksheet().getSheetFormatPr().getOutlineLevelRow());
workbook.close();
}
@ -553,10 +553,10 @@ public final class TestXSSFSheet extends BaseTestXSheet {
checkColumnGroup(cols.getColArray(3), 10, 11); // false, true
checkColumnGroup(cols.getColArray(4), 12, 12, false, false);
checkColumnGroup(cols.getColArray(5), 13, 13, false, false);
wb2.close();
}
/**
* Verify that column groups were created correctly after Sheet.groupColumn
*
@ -575,7 +575,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals("isSetHidden", isSetHidden, col.isSetHidden());
assertEquals("isSetCollapsed", isSetCollapsed, col.isSetCollapsed()); //not necessarily set
}
/**
* Verify that column groups were created correctly after Sheet.groupColumn
*
@ -708,7 +708,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertFalse(sheet1.getRow(16).getCTRow().isSetHidden());
assertFalse(sheet1.getRow(18).getCTRow().isSetCollapsed());
assertFalse(sheet1.getRow(18).getCTRow().isSetHidden());
wb2.close();
}
@ -755,7 +755,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals(4, col.getMax());
assertEquals(33.0, col.getWidth(), 0.0);
assertTrue(col.getCustomWidth());
workbook.close();
}
@ -801,7 +801,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
//now the span is splitted into 5 individual columns
assertEquals(5, cols.sizeOfColArray());
for (int i = 0; i < 5; i++) {
assertEquals(cw[i]*256, sheet.getColumnWidth(i));
assertEquals(cw[i]*256L, sheet.getColumnWidth(i));
assertEquals(cw[i], cols.getColArray(i).getWidth(), 0.0);
}
@ -812,10 +812,10 @@ public final class TestXSSFSheet extends BaseTestXSheet {
cols = sheet.getCTWorksheet().getColsArray(0);
assertEquals(5, cols.sizeOfColArray());
for (int i = 0; i < 5; i++) {
assertEquals(cw[i]*256, sheet.getColumnWidth(i));
assertEquals(cw[i]*256L, sheet.getColumnWidth(i));
assertEquals(cw[i], cols.getColArray(i).getWidth(), 0.0);
}
wb2.close();
}
@ -889,7 +889,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertFalse(sheet.isColumnHidden(3));
assertFalse(sheet.isColumnHidden(4));
assertFalse(sheet.isColumnHidden(5));
wb2.close();
}
@ -920,7 +920,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
//comment1 and comment2 are different objects
assertNotSame(comment1, comment2);
wb1.close();
//now test against a workbook containing cell comments
XSSFWorkbook wb2 = XSSFTestDataSamples.openSampleWorkbook("WithMoreVariousData.xlsx");
sheet1 = wb2.getSheetAt(0);
@ -928,7 +928,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertNotNull(comment1);
assertEquals("/xl/comments1.xml", comment1.getPackagePart().getPartName().getName());
assertSame(comment1, sheet1.getCommentsTable(true));
wb2.close();
}
@ -1034,7 +1034,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertTrue(nm.getCTName().getHidden());
assertEquals("_xlnm._FilterDatabase", nm.getCTName().getName());
assertEquals("'new sheet'!$A$1:$D$100", nm.getCTName().getStringValue());
wb.close();
}
@ -1057,7 +1057,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
sheet.protectSheet(null);
assertNull("protectSheet(null) should unset CTSheetProtection", sheet.getCTWorksheet().getSheetProtection());
wb.close();
}
@ -1095,12 +1095,12 @@ public final class TestXSSFSheet extends BaseTestXSheet {
wb1.close();
assertTrue(wb2.getSheetAt(0).validateSheetPassword(password));
wb2.close();
XSSFWorkbook wb3 = openSampleWorkbook("workbookProtection-sheet_password-2013.xlsx");
assertTrue(wb3.getSheetAt(0).validateSheetPassword("pwd"));
wb3.close();
}
@Test
public void bug49966() throws IOException {
@ -1161,7 +1161,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
XSSFSheet sheet = wb1.createSheet("Sheet 1");
assertFalse(sheet.getForceFormulaRecalculation());
// Set
sheet.setForceFormulaRecalculation(true);
assertTrue(sheet.getForceFormulaRecalculation());
@ -1221,7 +1221,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
}
swb.close();
}
wb.close();
}
@ -1246,7 +1246,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
}
swb.close();
}
wb.close();
}
@ -1295,7 +1295,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
name = wb.getBuiltInName(XSSFName.BUILTIN_FILTER_DB, 0);
assertNotNull(name);
assertEquals("Sheet0!$B:$C", name.getRefersToFormula());
wb.close();
}
@ -1389,7 +1389,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
XSSFPivotTable pivotTable = sheet2.createPivotTable
(wb.getCreationHelper().createAreaReference("A1:B2"), new CellReference("H5"), sheet1);
assertEquals(0, pivotTable.getRowLabelColumns().size());
assertEquals(1, wb.getPivotTables().size());
assertEquals(0, sheet1.getPivotTables().size());
assertEquals(1, sheet2.getPivotTables().size());
@ -1421,12 +1421,12 @@ public final class TestXSSFSheet extends BaseTestXSheet {
sheet2);
wb.close();
}
@Test(expected=POIXMLException.class)
public void testReadFails() throws IOException {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
// Throws exception because we cannot read here
try {
sheet.onDocumentRead();
@ -1434,8 +1434,8 @@ public final class TestXSSFSheet extends BaseTestXSheet {
wb.close();
}
}
/**
/**
* This would be better off as a testable example rather than a simple unit test
* since Sheet.createComment() was deprecated and removed.
* https://poi.apache.org/spreadsheet/quick-guide.html#CellComments
@ -1450,7 +1450,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertNotNull(comment);
wb.close();
}
protected void testCopyOneRow(String copyRowsTestWorkbook) throws IOException {
final double FLOAT_PRECISION = 1e-9;
final XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook(copyRowsTestWorkbook);
@ -1496,24 +1496,24 @@ public final class TestXSSFSheet extends BaseTestXSheet {
cell = CellUtil.getCell(destRow, col++);
assertEquals("[String] G7 cell type", CellType.STRING, cell.getCellType());
assertEquals("[String] G7 cell value", "Hello", cell.getStringCellValue());
// Int
cell = CellUtil.getCell(destRow, col++);
assertEquals("[Int] H7 cell type", CellType.NUMERIC, cell.getCellType());
assertEquals("[Int] H7 cell value", 15, (int) cell.getNumericCellValue());
// Float
cell = CellUtil.getCell(destRow, col++);
assertEquals("[Float] I7 cell type", CellType.NUMERIC, cell.getCellType());
assertEquals("[Float] I7 cell value", 12.5, cell.getNumericCellValue(), FLOAT_PRECISION);
// Cell Formula
cell = CellUtil.getCell(destRow, col++);
assertEquals("J7", new CellReference(cell).formatAsString());
assertEquals("[Cell Formula] J7 cell type", CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula] J7 cell formula", "5+2", cell.getCellFormula());
//System.out.println("Cell formula evaluation currently unsupported");
// Cell Formula with Reference
// Formula row references should be adjusted by destRowNum-srcRowNum
cell = CellUtil.getCell(destRow, col++);
@ -1522,21 +1522,21 @@ public final class TestXSSFSheet extends BaseTestXSheet {
CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula with Reference] K7 cell formula",
"J7+H$2", cell.getCellFormula());
// Cell Formula with Reference spanning multiple rows
cell = CellUtil.getCell(destRow, col++);
assertEquals("[Cell Formula with Reference spanning multiple rows] L7 cell type",
CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula with Reference spanning multiple rows] L7 cell formula",
"G7&\" \"&G8", cell.getCellFormula());
// Cell Formula with Reference spanning multiple rows
cell = CellUtil.getCell(destRow, col++);
assertEquals("[Cell Formula with Area Reference] M7 cell type",
CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula with Area Reference] M7 cell formula",
"SUM(H7:I8)", cell.getCellFormula());
// Array Formula
cell = CellUtil.getCell(destRow, col++);
//System.out.println("Array formulas currently unsupported");
@ -1545,7 +1545,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals("[Array Formula] N7 cell type", CellType.FORMULA, cell.getCellType());
assertEquals("[Array Formula] N7 cell formula", "{SUM(H7:J7*{1,2,3})}", cell.getCellFormula());
*/
// Data Format
cell = CellUtil.getCell(destRow, col++);
assertEquals("[Data Format] O7 cell type;", CellType.NUMERIC, cell.getCellType());
@ -1553,14 +1553,14 @@ public final class TestXSSFSheet extends BaseTestXSheet {
//FIXME: currently fails
final String moneyFormat = "\"$\"#,##0.00_);[Red]\\(\"$\"#,##0.00\\)";
assertEquals("[Data Format] O7 data format", moneyFormat, cell.getCellStyle().getDataFormatString());
// Merged
cell = CellUtil.getCell(destRow, col);
assertEquals("[Merged] P7:Q7 cell value",
"Merged cells", cell.getStringCellValue());
assertTrue("[Merged] P7:Q7 merged region",
sheet.getMergedRegions().contains(CellRangeAddress.valueOf("P7:Q7")));
// Merged across multiple rows
// Microsoft Excel 2013 does not copy a merged region unless all rows of
// the source merged region are selected
@ -1571,23 +1571,23 @@ public final class TestXSSFSheet extends BaseTestXSheet {
// which will not overwrite a cell in destination row if merged region extends beyond the copied row.
// The Excel way would require:
//assertEquals("[Merged across multiple rows] R7:S8 merged region", "Should NOT be overwritten", cell.getStringCellValue());
//assertFalse("[Merged across multiple rows] R7:S8 merged region",
//assertFalse("[Merged across multiple rows] R7:S8 merged region",
// sheet.getMergedRegions().contains(CellRangeAddress.valueOf("R7:S8")));
// As currently implemented, cell value is copied but merged region is not copied
assertEquals("[Merged across multiple rows] R7:S8 cell value",
"Merged cells across multiple rows", cell.getStringCellValue());
assertFalse("[Merged across multiple rows] R7:S7 merged region (one row)",
assertFalse("[Merged across multiple rows] R7:S7 merged region (one row)",
sheet.getMergedRegions().contains(CellRangeAddress.valueOf("R7:S7"))); //shouldn't do 1-row merge
assertFalse("[Merged across multiple rows] R7:S8 merged region",
assertFalse("[Merged across multiple rows] R7:S8 merged region",
sheet.getMergedRegions().contains(CellRangeAddress.valueOf("R7:S8"))); //shouldn't do 2-row merge
// Make sure other rows are blank (off-by-one errors)
assertNull(sheet.getRow(5));
assertNull(sheet.getRow(7));
wb.close();
}
protected void testCopyMultipleRows(String copyRowsTestWorkbook) throws IOException {
final double FLOAT_PRECISION = 1e-9;
final XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook(copyRowsTestWorkbook);
@ -1595,8 +1595,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
final CellCopyPolicy defaultCopyPolicy = new CellCopyPolicy();
sheet.copyRows(0, 3, 8, defaultCopyPolicy);
@SuppressWarnings("unused")
final Row srcHeaderRow = sheet.getRow(0);
sheet.getRow(0);
final Row srcRow1 = sheet.getRow(1);
final Row srcRow2 = sheet.getRow(2);
final Row srcRow3 = sheet.getRow(3);
@ -1606,102 +1605,102 @@ public final class TestXSSFSheet extends BaseTestXSheet {
final Row destRow3 = sheet.getRow(11);
int col = 0;
Cell cell;
// Header row should be copied
assertNotNull(destHeaderRow);
// Data rows
cell = CellUtil.getCell(destRow1, col);
assertEquals("Source row ->", cell.getStringCellValue());
// Style
col++;
cell = CellUtil.getCell(destRow1, col);
assertEquals("[Style] B10 cell value", "Red", cell.getStringCellValue());
assertEquals("[Style] B10 cell style", CellUtil.getCell(srcRow1, 1).getCellStyle(), cell.getCellStyle());
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Style] B11 cell value", "Blue", cell.getStringCellValue());
assertEquals("[Style] B11 cell style", CellUtil.getCell(srcRow2, 1).getCellStyle(), cell.getCellStyle());
// Blank
col++;
cell = CellUtil.getCell(destRow1, col);
assertEquals("[Blank] C10 cell type", CellType.BLANK, cell.getCellType());
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Blank] C11 cell type", CellType.BLANK, cell.getCellType());
// Error
col++;
cell = CellUtil.getCell(destRow1, col);
assertEquals("[Error] D10 cell type", CellType.ERROR, cell.getCellType());
FormulaError error = FormulaError.forInt(cell.getErrorCellValue());
assertEquals("[Error] D10 cell value", FormulaError.NA, error); //FIXME: XSSFCell and HSSFCell expose different interfaces. getErrorCellString would be helpful here
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Error] D11 cell type", CellType.ERROR, cell.getCellType());
error = FormulaError.forInt(cell.getErrorCellValue());
assertEquals("[Error] D11 cell value", FormulaError.NAME, error); //FIXME: XSSFCell and HSSFCell expose different interfaces. getErrorCellString would be helpful here
// Date
col++;
cell = CellUtil.getCell(destRow1, col);
assertEquals("[Date] E10 cell type", CellType.NUMERIC, cell.getCellType());
Date date = LocaleUtil.getLocaleCalendar(2000, Calendar.JANUARY, 1).getTime();
assertEquals("[Date] E10 cell value", date, cell.getDateCellValue());
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Date] E11 cell type", CellType.NUMERIC, cell.getCellType());
date = LocaleUtil.getLocaleCalendar(2000, Calendar.JANUARY, 2).getTime();
assertEquals("[Date] E11 cell value", date, cell.getDateCellValue());
// Boolean
col++;
cell = CellUtil.getCell(destRow1, col);
assertEquals("[Boolean] F10 cell type", CellType.BOOLEAN, cell.getCellType());
assertEquals("[Boolean] F10 cell value", true, cell.getBooleanCellValue());
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Boolean] F11 cell type", CellType.BOOLEAN, cell.getCellType());
assertEquals("[Boolean] F11 cell value", false, cell.getBooleanCellValue());
// String
col++;
cell = CellUtil.getCell(destRow1, col);
assertEquals("[String] G10 cell type", CellType.STRING, cell.getCellType());
assertEquals("[String] G10 cell value", "Hello", cell.getStringCellValue());
cell = CellUtil.getCell(destRow2, col);
assertEquals("[String] G11 cell type", CellType.STRING, cell.getCellType());
assertEquals("[String] G11 cell value", "World", cell.getStringCellValue());
// Int
col++;
cell = CellUtil.getCell(destRow1, col);
assertEquals("[Int] H10 cell type", CellType.NUMERIC, cell.getCellType());
assertEquals("[Int] H10 cell value", 15, (int) cell.getNumericCellValue());
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Int] H11 cell type", CellType.NUMERIC, cell.getCellType());
assertEquals("[Int] H11 cell value", 42, (int) cell.getNumericCellValue());
// Float
col++;
cell = CellUtil.getCell(destRow1, col);
assertEquals("[Float] I10 cell type", CellType.NUMERIC, cell.getCellType());
assertEquals("[Float] I10 cell value", 12.5, cell.getNumericCellValue(), FLOAT_PRECISION);
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Float] I11 cell type", CellType.NUMERIC, cell.getCellType());
assertEquals("[Float] I11 cell value", 5.5, cell.getNumericCellValue(), FLOAT_PRECISION);
// Cell Formula
col++;
cell = CellUtil.getCell(destRow1, col);
assertEquals("[Cell Formula] J10 cell type", CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula] J10 cell formula", "5+2", cell.getCellFormula());
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Cell Formula] J11 cell type", CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula] J11 cell formula", "6+18", cell.getCellFormula());
@ -1714,11 +1713,11 @@ public final class TestXSSFSheet extends BaseTestXSheet {
CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula with Reference] K10 cell formula",
"J10+H$2", cell.getCellFormula());
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Cell Formula with Reference] K11 cell type", CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula with Reference] K11 cell formula", "J11+H$2", cell.getCellFormula());
// Cell Formula with Reference spanning multiple rows
col++;
cell = CellUtil.getCell(destRow1, col);
@ -1726,13 +1725,13 @@ public final class TestXSSFSheet extends BaseTestXSheet {
CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula with Reference spanning multiple rows] L10 cell formula",
"G10&\" \"&G11", cell.getCellFormula());
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Cell Formula with Reference spanning multiple rows] L11 cell type",
CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula with Reference spanning multiple rows] L11 cell formula",
"G11&\" \"&G12", cell.getCellFormula());
// Cell Formula with Area Reference
col++;
cell = CellUtil.getCell(destRow1, col);
@ -1740,13 +1739,13 @@ public final class TestXSSFSheet extends BaseTestXSheet {
CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula with Area Reference] M10 cell formula",
"SUM(H10:I11)", cell.getCellFormula());
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Cell Formula with Area Reference] M11 cell type",
CellType.FORMULA, cell.getCellType());
assertEquals("[Cell Formula with Area Reference] M11 cell formula",
"SUM($H$3:I10)", cell.getCellFormula()); //Also acceptable: SUM($H10:I$3), but this AreaReference isn't in ascending order
// Array Formula
col++;
cell = CellUtil.getCell(destRow1, col);
@ -1755,13 +1754,13 @@ public final class TestXSSFSheet extends BaseTestXSheet {
// FIXME: Array Formula set with Sheet.setArrayFormula() instead of cell.setFormula()
assertEquals("[Array Formula] N10 cell type", CellType.FORMULA, cell.getCellType());
assertEquals("[Array Formula] N10 cell formula", "{SUM(H10:J10*{1,2,3})}", cell.getCellFormula());
cell = CellUtil.getCell(destRow2, col);
// FIXME: Array Formula set with Sheet.setArrayFormula() instead of cell.setFormula()
// FIXME: Array Formula set with Sheet.setArrayFormula() instead of cell.setFormula()
assertEquals("[Array Formula] N11 cell type", CellType.FORMULA, cell.getCellType());
assertEquals("[Array Formula] N11 cell formula", "{SUM(H11:J11*{1,2,3})}", cell.getCellFormula());
*/
// Data Format
col++;
cell = CellUtil.getCell(destRow2, col);
@ -1769,7 +1768,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals("[Data Format] O10 cell value", 100.20, cell.getNumericCellValue(), FLOAT_PRECISION);
final String moneyFormat = "\"$\"#,##0.00_);[Red]\\(\"$\"#,##0.00\\)";
assertEquals("[Data Format] O10 cell data format", moneyFormat, cell.getCellStyle().getDataFormatString());
// Merged
col++;
cell = CellUtil.getCell(destRow1, col);
@ -1777,42 +1776,42 @@ public final class TestXSSFSheet extends BaseTestXSheet {
"Merged cells", cell.getStringCellValue());
assertTrue("[Merged] P10:Q10 merged region",
sheet.getMergedRegions().contains(CellRangeAddress.valueOf("P10:Q10")));
cell = CellUtil.getCell(destRow2, col);
assertEquals("[Merged] P11:Q11 cell value", "Merged cells", cell.getStringCellValue());
assertTrue("[Merged] P11:Q11 merged region",
sheet.getMergedRegions().contains(CellRangeAddress.valueOf("P11:Q11")));
// Should Q10/Q11 be checked?
// Merged across multiple rows
// Microsoft Excel 2013 does not copy a merged region unless all rows of
// the source merged region are selected
// POI's behavior should match this behavior
col += 2;
cell = CellUtil.getCell(destRow1, col);
assertEquals("[Merged across multiple rows] R10:S11 cell value",
assertEquals("[Merged across multiple rows] R10:S11 cell value",
"Merged cells across multiple rows", cell.getStringCellValue());
assertTrue("[Merged across multiple rows] R10:S11 merged region",
assertTrue("[Merged across multiple rows] R10:S11 merged region",
sheet.getMergedRegions().contains(CellRangeAddress.valueOf("R10:S11")));
// Row 3 (zero-based) was empty, so Row 11 (zero-based) should be empty too.
if (srcRow3 == null) {
assertNull("Row 3 was empty, so Row 11 should be empty", destRow3);
}
// Make sure other rows are blank (off-by-one errors)
assertNull("Off-by-one lower edge case", sheet.getRow(7)); //one row above destHeaderRow
assertNull("Off-by-one upper edge case", sheet.getRow(12)); //one row below destRow3
wb.close();
}
@Test
public void testCopyOneRow() throws IOException {
testCopyOneRow("XSSFSheet.copyRows.xlsx");
}
@Test
public void testCopyMultipleRows() throws IOException {
testCopyMultipleRows("XSSFSheet.copyRows.xlsx");
@ -1828,12 +1827,12 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals(1, ignoredError.getSqref().size());
assertEquals("B2:D4", ignoredError.getSqref().get(0));
assertTrue(ignoredError.getNumberStoredAsText());
Map<IgnoredErrorType, Set<CellRangeAddress>> ignoredErrors = sheet.getIgnoredErrors();
assertEquals(1, ignoredErrors.size());
assertEquals(1, ignoredErrors.get(IgnoredErrorType.NUMBER_STORED_AS_TEXT).size());
assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.NUMBER_STORED_AS_TEXT).iterator().next().formatAsString());
workbook.close();
}
@ -1849,7 +1848,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertFalse(ignoredError.getNumberStoredAsText());
assertTrue(ignoredError.getFormula());
assertTrue(ignoredError.getEvalError());
Map<IgnoredErrorType, Set<CellRangeAddress>> ignoredErrors = sheet.getIgnoredErrors();
assertEquals(2, ignoredErrors.size());
assertEquals(1, ignoredErrors.get(IgnoredErrorType.FORMULA).size());
@ -1867,19 +1866,19 @@ public final class TestXSSFSheet extends BaseTestXSheet {
// Two calls means two elements, no clever collapsing just yet.
sheet.addIgnoredErrors(region, IgnoredErrorType.EVALUATION_ERROR);
sheet.addIgnoredErrors(region, IgnoredErrorType.FORMULA);
CTIgnoredError ignoredError = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(0);
assertEquals(1, ignoredError.getSqref().size());
assertEquals("B2:D4", ignoredError.getSqref().get(0));
assertFalse(ignoredError.getFormula());
assertTrue(ignoredError.getEvalError());
ignoredError = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(1);
assertEquals(1, ignoredError.getSqref().size());
assertEquals("B2:D4", ignoredError.getSqref().get(0));
assertTrue(ignoredError.getFormula());
assertFalse(ignoredError.getEvalError());
Map<IgnoredErrorType, Set<CellRangeAddress>> ignoredErrors = sheet.getIgnoredErrors();
assertEquals(2, ignoredErrors.size());
assertEquals(1, ignoredErrors.get(IgnoredErrorType.FORMULA).size());
@ -1888,7 +1887,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.EVALUATION_ERROR).iterator().next().formatAsString());
workbook.close();
}
@Test
public void setTabColor() throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
@ -1900,7 +1899,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
sh.getCTWorksheet().getSheetPr().getTabColor().getIndexed());
}
}
@Test
public void getTabColor() throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
@ -1912,7 +1911,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals(expected, sh.getTabColor());
}
}
// Test using an existing workbook saved by Excel
@Test
public void tabColor() throws IOException {
@ -1930,7 +1929,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
assertEquals(expected, wb.getSheet("customOrange").getTabColor());
}
}
/**
* See bug #52425
*/
@ -1947,7 +1946,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
// Adding Comment to cloned Sheet 3
addComments(helper, sheet3);
}
private void addComments(CreationHelper helper, Sheet sheet) {
Drawing<?> drawing = sheet.createDrawingPatriarch();
@ -1974,7 +1973,7 @@ public final class TestXSSFSheet extends BaseTestXSheet {
}
}
// bug 59687: XSSFSheet.RemoveRow doesn't handle row gaps properly when removing row comments
@Test
public void testRemoveRowWithCommentAndGapAbove() throws IOException {
@ -1984,22 +1983,22 @@ public final class TestXSSFSheet extends BaseTestXSheet {
// comment exists
CellAddress commentCellAddress = new CellAddress("A4");
assertNotNull(sheet.getCellComment(commentCellAddress));
assertEquals("Wrong starting # of comments", 1, sheet.getCellComments().size());
sheet.removeRow(sheet.getRow(commentCellAddress.getRow()));
assertEquals("There should not be any comments left!", 0, sheet.getCellComments().size());
}
@Test
public void testGetHeaderFooterProperties() throws IOException {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sh = wb.createSheet();
XSSFHeaderFooterProperties hfProp = sh.getHeaderFooterProperties();
assertNotNull(hfProp);
wb.close();
}
}

View File

@ -1044,8 +1044,10 @@ public final class TestXSSFWorkbook extends BaseTestXWorkbook {
//assertCloseDoesNotModifyFile(filename, wb);
// InputStream
wb = new XSSFWorkbook(new FileInputStream(file));
assertCloseDoesNotModifyFile(filename, wb);
try (FileInputStream is = new FileInputStream(file)) {
wb = new XSSFWorkbook(is);
assertCloseDoesNotModifyFile(filename, wb);
}
// OPCPackage
//wb = new XSSFWorkbook(OPCPackage.open(file));

View File

@ -65,7 +65,7 @@ public class TestXSSFChartTitle {
row = sheet.createRow((short) rowIndex);
for (int colIndex = 0; colIndex < NUM_OF_COLUMNS; colIndex++) {
cell = row.createCell((short) colIndex);
cell.setCellValue(colIndex * (rowIndex + 1));
cell.setCellValue(colIndex * (rowIndex + 1L));
}
}

View File

@ -25,6 +25,9 @@ import static org.junit.Assert.assertTrue;
import java.io.IOException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFSheet;
@ -192,14 +195,14 @@ public final class TestColumnHelper {
}
@Test
public void testAddCleanColIntoColsExactOverlap() throws Exception {
public void testAddCleanColIntoColsExactOverlap() {
CTCols cols = createHiddenAndBestFitColsWithHelper(1, 1, 1, 1);
assertEquals(1, cols.sizeOfColArray());
assertMinMaxHiddenBestFit(cols, 0, 1, 1, true, true);
}
@Test
public void testAddCleanColIntoColsOverlapsOverhangingBothSides() throws Exception {
public void testAddCleanColIntoColsOverlapsOverhangingBothSides() {
CTCols cols = createHiddenAndBestFitColsWithHelper(2, 2, 1, 3);
assertEquals(3, cols.sizeOfColArray());
assertMinMaxHiddenBestFit(cols, 0, 1, 1, false, true);
@ -208,7 +211,7 @@ public final class TestColumnHelper {
}
@Test
public void testAddCleanColIntoColsOverlapsCompletelyNested() throws Exception {
public void testAddCleanColIntoColsOverlapsCompletelyNested() {
CTCols cols = createHiddenAndBestFitColsWithHelper(1, 3, 2, 2);
assertEquals(3, cols.sizeOfColArray());
assertMinMaxHiddenBestFit(cols, 0, 1, 1, true, false);
@ -217,7 +220,7 @@ public final class TestColumnHelper {
}
@Test
public void testAddCleanColIntoColsNewOverlapsOverhangingLeftNotRightExactRight() throws Exception {
public void testAddCleanColIntoColsNewOverlapsOverhangingLeftNotRightExactRight() {
CTCols cols = createHiddenAndBestFitColsWithHelper(2, 3, 1, 3);
assertEquals(2, cols.sizeOfColArray());
assertMinMaxHiddenBestFit(cols, 0, 1, 1, false, true);
@ -225,7 +228,7 @@ public final class TestColumnHelper {
}
@Test
public void testAddCleanColIntoColsNewOverlapsOverhangingRightNotLeftExactLeft() throws Exception {
public void testAddCleanColIntoColsNewOverlapsOverhangingRightNotLeftExactLeft() {
CTCols cols = createHiddenAndBestFitColsWithHelper(1, 2, 1, 3);
assertEquals(2, cols.sizeOfColArray());
assertMinMaxHiddenBestFit(cols, 0, 1, 2, true, true);
@ -233,7 +236,7 @@ public final class TestColumnHelper {
}
@Test
public void testAddCleanColIntoColsNewOverlapsOverhangingLeftNotRight() throws Exception {
public void testAddCleanColIntoColsNewOverlapsOverhangingLeftNotRight() {
CTCols cols = createHiddenAndBestFitColsWithHelper(2, 3, 1, 2);
assertEquals(3, cols.sizeOfColArray());
assertMinMaxHiddenBestFit(cols, 0, 1, 1, false, true);
@ -242,7 +245,7 @@ public final class TestColumnHelper {
}
@Test
public void testAddCleanColIntoColsNewOverlapsOverhangingRightNotLeft() throws Exception {
public void testAddCleanColIntoColsNewOverlapsOverhangingRightNotLeft() {
CTCols cols = createHiddenAndBestFitColsWithHelper(1, 2, 2, 3);
assertEquals(3, cols.sizeOfColArray());
assertMinMaxHiddenBestFit(cols, 0, 1, 1, true, false);
@ -402,4 +405,36 @@ public final class TestColumnHelper {
}
return count;
}
@SuppressWarnings("deprecation")
@Test
public void testColumnsCollapsed() {
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet("test");
Row row = sheet.createRow(0);
row.createCell(0);
row.createCell(1);
row.createCell(2);
sheet.setColumnWidth(0, 10);
sheet.setColumnWidth(1, 10);
sheet.setColumnWidth(2, 10);
sheet.groupColumn(0, 1);
sheet.setColumnGroupCollapsed(0, true);
CTCols ctCols = ((XSSFSheet) sheet).getCTWorksheet().getColsArray()[0];
assertEquals(3, ctCols.sizeOfColArray());
assertTrue(ctCols.getColArray(0).isSetCollapsed());
assertTrue(ctCols.getColArray(1).isSetCollapsed());
assertTrue(ctCols.getColArray(2).isSetCollapsed());
ColumnHelper helper = new ColumnHelper(CTWorksheet.Factory.newInstance());
helper.setColumnAttributes(ctCols.getColArray(1), ctCols.getColArray(2));
ctCols = ((XSSFSheet) sheet).getCTWorksheet().getColsArray()[0];
assertTrue(ctCols.getColArray(0).isSetCollapsed());
assertTrue(ctCols.getColArray(1).isSetCollapsed());
assertTrue(ctCols.getColArray(2).isSetCollapsed());
}
}

View File

@ -17,18 +17,23 @@
package org.apache.poi.xssf.util;
import junit.framework.TestCase;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.util.CellReference;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
import java.util.List;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType;
import junit.framework.TestCase;
/**
* Mixed utilities for testing memory usage in XSSF
@ -37,7 +42,7 @@ import java.util.ArrayList;
*/
public class MemoryUsage extends TestCase {
private static final int NUM_COLUMNS = 255;
private static void printMemoryUsage(String msg) {
System.out.println(" Memory (" + msg + "): " + Runtime.getRuntime().totalMemory()/(1024*1024) + "MB");
}
@ -62,8 +67,11 @@ public class MemoryUsage extends TestCase {
Row row = sh.createRow(i);
for(int j=0; j < numCols; j++){
Cell cell = row.createCell(j);
if(j % 2 == 0) cell.setCellValue(j);
else cell.setCellValue(new CellReference(j, i).formatAsString());
if(j % 2 == 0) {
cell.setCellValue(j);
} else {
cell.setCellValue(new CellReference(j, i).formatAsString());
}
cnt++;
}
}
@ -78,7 +86,7 @@ public class MemoryUsage extends TestCase {
/**
* Generate a spreadsheet who's all cell values are numbers.
* The data is generated until OutOfMemoryError.
* The data is generated until OutOfMemoryError.
* <p>
* as compared to {@link #mixedSpreadsheet(org.apache.poi.ss.usermodel.Workbook, int)},
* this method does not set string values and, hence, does not involve the Shared Strings Table.
@ -161,7 +169,7 @@ public class MemoryUsage extends TestCase {
rows.add(r);
}
} catch (OutOfMemoryError er) {
System.out.println("Failed at row=" + i);
System.out.println("Failed at row=" + i + " from " + rows.size() + " kept.");
} catch (final Exception e) {
System.out.println("Unable to reach an OutOfMemoryError");
System.out.println(e.getClass().getName() + ": " + e.getMessage());
@ -190,7 +198,7 @@ public class MemoryUsage extends TestCase {
rows.add(r);
}
} catch (OutOfMemoryError er) {
System.out.println("Failed at row=" + i);
System.out.println("Failed at row=" + i + " from " + rows.size() + " kept.");
} catch (final Exception e) {
System.out.println("Unable to reach an OutOfMemoryError");
System.out.println(e.getClass().getName() + ": " + e.getMessage());

View File

@ -29,6 +29,7 @@ import org.apache.poi.xwpf.XWPFTestDataSamples;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import static org.apache.poi.POITestCase.assertContains;
import static org.apache.poi.POITestCase.assertEndsWith;
import static org.apache.poi.POITestCase.assertNotContained;
import static org.apache.poi.POITestCase.assertStartsWith;
/**
@ -441,4 +442,14 @@ public class TestXWPFWordExtractor extends TestCase {
assertContains(txt, "Sequencing data");
extractor.close();
}
public void testGlossary() throws IOException {
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("60316.dotx");
XWPFWordExtractor extractor = new XWPFWordExtractor(doc);
String txt = extractor.getText();
assertContains(txt, "Getting the perfect");
//this content appears only in the glossary document
//once we add processing for this, we can change this to contains
assertNotContained(txt, "table rows");
}
}

View File

@ -148,6 +148,19 @@ public final class TestXWPFSDT {
assertEquals("", sdts.get(0).getTitle());
}
@Test
public void test62859() throws IOException {
//this doesn't test the exact code path for this issue, but
//it does test for a related issue, and the fix fixes both.
//We should try to add the actual triggering document
//to our test suite.
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug62859.docx");
List<XWPFAbstractSDT> sdts = extractAllSDTs(doc);
assertEquals(1, sdts.size());
assertEquals("", sdts.get(0).getTag());
assertEquals("", sdts.get(0).getTitle());
}
private List<XWPFAbstractSDT> extractAllSDTs(XWPFDocument doc) {
List<XWPFAbstractSDT> sdts = new ArrayList<>();

View File

@ -75,33 +75,25 @@ import org.apache.poi.util.LittleEndian;
* @author Sergey Vladimirov (vlsergey at gmail dot com)
*/
@Beta
public final class HWPFLister
{
private static HWPFDocumentCore loadDoc( File docFile ) throws IOException
{
public final class HWPFLister {
private static HWPFDocumentCore loadDoc( File docFile ) throws IOException {
try (final FileInputStream istream = new FileInputStream( docFile )) {
return loadDoc( istream );
}
}
private static HWPFDocumentCore loadDoc( InputStream inputStream )
throws IOException
{
final POIFSFileSystem poifsFileSystem = HWPFDocumentCore.verifyAndBuildPOIFS( inputStream );
try
{
throws IOException {
final POIFSFileSystem poifsFileSystem = HWPFDocumentCore.verifyAndBuildPOIFS( inputStream ); // NOSONAR
try {
return new HWPFDocument( poifsFileSystem );
}
catch ( OldWordFileFormatException exc )
{
} catch ( OldWordFileFormatException exc ) {
return new HWPFOldDocument( poifsFileSystem );
}
}
public static void main( String[] args ) throws Exception
{
if ( args.length == 0 )
{
public static void main( String[] args ) throws Exception {
if ( args.length == 0 ) {
System.err.println( "Use:" );
System.err.println( "\tHWPFLister <filename>\n" + "\t\t[--dop]\n"
+ "\t\t[--textPieces] [--textPiecesText]\n"
@ -140,8 +132,7 @@ public final class HWPFLister
boolean writereadback = false;
for ( String arg : Arrays.asList( args ).subList( 1, args.length ) )
{
for ( String arg : Arrays.asList( args ).subList( 1, args.length ) ) {
if ( "--dop".equals( arg ) )
outputDop = true;
@ -190,17 +181,14 @@ public final class HWPFLister
if ( writereadback )
doc = writeOutAndReadBack( doc );
HWPFDocumentCore original;
{
System.setProperty( "org.apache.poi.hwpf.preserveBinTables",
Boolean.TRUE.toString() );
System.setProperty( "org.apache.poi.hwpf.preserveTextTable",
Boolean.TRUE.toString() );
System.setProperty( "org.apache.poi.hwpf.preserveBinTables",
Boolean.TRUE.toString() );
System.setProperty( "org.apache.poi.hwpf.preserveTextTable",
Boolean.TRUE.toString() );
original = loadDoc( new File( args[0] ) );
if ( writereadback )
original = writeOutAndReadBack( original );
}
HWPFDocumentCore original = loadDoc( new File( args[0] ) );
if ( writereadback )
original = writeOutAndReadBack( original );
HWPFLister listerOriginal = new HWPFLister( original );
HWPFLister listerRebuilded = new HWPFLister( doc );
@ -211,20 +199,17 @@ public final class HWPFLister
System.out.println( "== FIB (original) ==" );
listerOriginal.dumpFIB();
if ( outputDop )
{
if ( outputDop ) {
System.out.println( "== Document properties ==" );
listerOriginal.dumpDop();
}
if ( outputTextPieces )
{
if ( outputTextPieces ) {
System.out.println( "== Text pieces (original) ==" );
listerOriginal.dumpTextPieces( outputTextPiecesText );
}
if ( outputChpx )
{
if ( outputChpx ) {
System.out.println( "== CHPX (original) ==" );
listerOriginal.dumpChpx( outputChpxProperties, outputChpxSprms );
@ -232,8 +217,7 @@ public final class HWPFLister
listerRebuilded.dumpChpx( outputChpxProperties, outputChpxSprms );
}
if ( outputPapx )
{
if ( outputPapx ) {
System.out.println( "== PAPX (original) ==" );
listerOriginal.dumpPapx( outputPapxProperties, outputPapxSprms );
@ -241,8 +225,7 @@ public final class HWPFLister
listerRebuilded.dumpPapx( outputPapxProperties, outputPapxSprms );
}
if ( outputParagraphs )
{
if ( outputParagraphs ) {
System.out.println( "== Text paragraphs (original) ==" );
listerRebuilded.dumpParagraphs( true );
@ -250,56 +233,47 @@ public final class HWPFLister
listerRebuilded.dumpParagraphsDom( outputParagraphsText );
}
if ( outputBookmarks )
{
if ( outputBookmarks ) {
System.out.println( "== BOOKMARKS (rebuilded) ==" );
listerRebuilded.dumpBookmarks();
}
if ( outputEscher )
{
if ( outputEscher ) {
System.out.println( "== ESCHER PROPERTIES (rebuilded) ==" );
listerRebuilded.dumpEscher();
}
if ( outputFields )
{
if ( outputFields ) {
System.out.println( "== FIELDS (rebuilded) ==" );
listerRebuilded.dumpFields();
}
if ( outputOfficeDrawings )
{
if ( outputOfficeDrawings ) {
System.out.println( "== OFFICE DRAWINGS (rebuilded) ==" );
listerRebuilded.dumpOfficeDrawings();
}
if ( outputPictures )
{
if ( outputPictures ) {
System.out.println( "== PICTURES (rebuilded) ==" );
listerRebuilded.dumpPictures();
}
if ( outputStyles )
{
if ( outputStyles ) {
System.out.println( "== STYLES (rebuilded) ==" );
listerRebuilded.dumpStyles();
}
}
private static HWPFDocumentCore writeOutAndReadBack(
HWPFDocumentCore original )
{
try
{
HWPFDocumentCore original ) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream( 4096 );
original.write( baos );
ByteArrayInputStream bais = new ByteArrayInputStream(
baos.toByteArray() );
return loadDoc( bais );
}
catch ( IOException e )
{
catch ( IOException e ) {
throw new RuntimeException( e );
}
}
@ -308,82 +282,67 @@ public final class HWPFLister
private LinkedHashMap<Integer, String> paragraphs;
public HWPFLister( HWPFDocumentCore doc )
{
public HWPFLister( HWPFDocumentCore doc ) {
_doc = doc;
buildParagraphs();
}
private void buildParagraphs()
{
private void buildParagraphs() {
paragraphs = new LinkedHashMap<>();
StringBuilder part = new StringBuilder();
String text = _doc.getDocumentText();
for ( int charIndex = 0; charIndex < text.length(); charIndex++ )
{
for ( int charIndex = 0; charIndex < text.length(); charIndex++ ) {
char c = text.charAt( charIndex );
part.append( c );
if ( c == 13 || c == 7 || c == 12 )
{
if ( c == 13 || c == 7 || c == 12 ) {
paragraphs.put( Integer.valueOf( charIndex ), part.toString() );
part.setLength( 0 );
}
}
}
private void dumpBookmarks()
{
if ( !( _doc instanceof HWPFDocument ) )
{
private void dumpBookmarks() {
if ( !( _doc instanceof HWPFDocument ) ) {
System.out.println( "Word 95 not supported so far" );
return;
}
HWPFDocument document = (HWPFDocument) _doc;
Bookmarks bookmarks = document.getBookmarks();
for ( int b = 0; b < bookmarks.getBookmarksCount(); b++ )
{
for ( int b = 0; b < bookmarks.getBookmarksCount(); b++ ) {
Bookmark bookmark = bookmarks.getBookmark( b );
System.out.println( "[" + bookmark.getStart() + "; "
+ bookmark.getEnd() + "): " + bookmark.getName() );
}
}
public void dumpChpx( boolean withProperties, boolean withSprms )
{
for ( CHPX chpx : _doc.getCharacterTable().getTextRuns() )
{
public void dumpChpx( boolean withProperties, boolean withSprms ) {
for ( CHPX chpx : _doc.getCharacterTable().getTextRuns() ) {
System.out.println( chpx );
if ( withProperties )
{
if ( withProperties ) {
System.out.println( chpx.getCharacterProperties(
_doc.getStyleSheet(), (short) StyleSheet.NIL_STYLE ) );
}
if ( withSprms )
{
if ( withSprms ) {
SprmIterator sprmIt = new SprmIterator( chpx.getGrpprl(), 0 );
while ( sprmIt.hasNext() )
{
while ( sprmIt.hasNext() ) {
SprmOperation sprm = sprmIt.next();
System.out.println( "\t" + sprm);
}
}
String text = new Range( chpx.getStart(), chpx.getEnd(),
_doc.getOverallRange() )
{
public String toString()
{
_doc.getOverallRange() ) {
public String toString() {
return "CHPX range (" + super.toString() + ")";
}
}.text();
StringBuilder stringBuilder = new StringBuilder();
for ( char c : text.toCharArray() )
{
for ( char c : text.toCharArray() ) {
if ( c < 30 )
stringBuilder.append("\\0x").append(Integer.toHexString(c));
else
@ -393,10 +352,8 @@ public final class HWPFLister
}
}
private void dumpDop()
{
if ( !( _doc instanceof HWPFDocument ) )
{
private void dumpDop() {
if ( !( _doc instanceof HWPFDocument ) ) {
System.out.println( "Word 95 not supported so far" );
return;
}
@ -404,10 +361,8 @@ public final class HWPFLister
System.out.println( ( (HWPFDocument) _doc ).getDocProperties() );
}
private void dumpEscher()
{
if ( _doc instanceof HWPFOldDocument )
{
private void dumpEscher() {
if ( _doc instanceof HWPFOldDocument ) {
System.out.println( "Word 95 not supported so far" );
return;
}
@ -415,46 +370,38 @@ public final class HWPFLister
System.out.println( ( (HWPFDocument) _doc ).getEscherRecordHolder() );
}
public void dumpFIB()
{
public void dumpFIB() {
FileInformationBlock fib = _doc.getFileInformationBlock();
System.out.println( fib );
}
private void dumpFields()
{
if ( !( _doc instanceof HWPFDocument ) )
{
private void dumpFields() {
if ( !( _doc instanceof HWPFDocument ) ) {
System.out.println( "Word 95 not supported so far" );
return;
}
HWPFDocument document = (HWPFDocument) _doc;
for ( FieldsDocumentPart part : FieldsDocumentPart.values() )
{
for ( FieldsDocumentPart part : FieldsDocumentPart.values() ) {
System.out.println( "=== Document part: " + part + " ===" );
for ( Field field : document.getFields().getFields( part ) )
{
for ( Field field : document.getFields().getFields( part ) ) {
System.out.println( field );
}
}
}
public void dumpFileSystem() throws Exception
{
public void dumpFileSystem() throws Exception {
System.out.println( dumpFileSystem( _doc.getDirectory() ) );
}
private String dumpFileSystem( DirectoryEntry directory )
{
private String dumpFileSystem( DirectoryEntry directory ) {
StringBuilder result = new StringBuilder();
result.append( "+ " );
result.append( directory.getName() );
for ( Iterator<Entry> iterator = directory.getEntries(); iterator
.hasNext(); )
{
.hasNext(); ) {
Entry entry = iterator.next();
String entryToString = "\n" + dumpFileSystem( entry );
entryToString = entryToString.replaceAll( "\n", "\n+---" );
@ -464,50 +411,41 @@ public final class HWPFLister
return result.toString();
}
private String dumpFileSystem( Entry entry )
{
private String dumpFileSystem( Entry entry ) {
if ( entry instanceof DirectoryEntry )
return dumpFileSystem( (DirectoryEntry) entry );
return entry.getName();
}
private void dumpOfficeDrawings()
{
if ( !( _doc instanceof HWPFDocument ) )
{
private void dumpOfficeDrawings() {
if ( !( _doc instanceof HWPFDocument ) ) {
System.out.println( "Word 95 not supported so far" );
return;
}
HWPFDocument document = (HWPFDocument) _doc;
if ( document.getOfficeDrawingsHeaders() != null )
{
if ( document.getOfficeDrawingsHeaders() != null ) {
System.out.println( "=== Document part: HEADER ===" );
for ( OfficeDrawing officeDrawing : document
.getOfficeDrawingsHeaders().getOfficeDrawings() )
{
.getOfficeDrawingsHeaders().getOfficeDrawings() ) {
System.out.println( officeDrawing );
}
}
if ( document.getOfficeDrawingsHeaders() != null )
{
if ( document.getOfficeDrawingsHeaders() != null ) {
System.out.println( "=== Document part: MAIN ===" );
for ( OfficeDrawing officeDrawing : document
.getOfficeDrawingsMain().getOfficeDrawings() )
{
.getOfficeDrawingsMain().getOfficeDrawings() ) {
System.out.println( officeDrawing );
}
}
}
public void dumpPapx( boolean withProperties, boolean withSprms )
throws Exception
{
if ( _doc instanceof HWPFDocument )
{
throws Exception {
if ( _doc instanceof HWPFDocument ) {
System.out.println( "binary PAP pages " );
HWPFDocument doc = (HWPFDocument) _doc;
@ -521,8 +459,7 @@ public final class HWPFLister
List<PAPX> papxs = new ArrayList<>();
int length = binTable.length();
for ( int x = 0; x < length; x++ )
{
for ( int x = 0; x < length; x++ ) {
GenericPropertyNode node = binTable.getProperty( x );
int pageNum = LittleEndian.getInt( node.getBytes() );
@ -535,12 +472,10 @@ public final class HWPFLister
System.out.println( "* PFKP: " + pfkp );
for ( PAPX papx : pfkp.getPAPXs() )
{
for ( PAPX papx : pfkp.getPAPXs() ) {
System.out.println( "** " + papx );
papxs.add( papx );
if ( papx != null && withSprms )
{
if ( papx != null && withSprms ) {
SprmIterator sprmIt = new SprmIterator(
papx.getGrpprl(), 2 );
dumpSprms( sprmIt, "*** " );
@ -551,11 +486,9 @@ public final class HWPFLister
Collections.sort( papxs );
System.out.println( "* Sorted by END" );
for ( PAPX papx : papxs )
{
for ( PAPX papx : papxs ) {
System.out.println( "** " + papx );
if ( papx != null && withSprms )
{
if ( papx != null && withSprms ) {
SprmIterator sprmIt = new SprmIterator( papx.getGrpprl(), 2 );
dumpSprms( sprmIt, "*** " );
}
@ -563,12 +496,10 @@ public final class HWPFLister
}
for ( PAPX papx : _doc.getParagraphTable().getParagraphs() )
{
for ( PAPX papx : _doc.getParagraphTable().getParagraphs() ) {
System.out.println( papx );
if ( withProperties )
{
if ( withProperties ) {
Paragraph paragraph = Paragraph.newParagraph( _doc.getOverallRange(), papx );
System.out.println( paragraph.getProps() );
}
@ -578,23 +509,18 @@ public final class HWPFLister
}
}
public void dumpParagraphs( boolean dumpAssotiatedPapx )
{
for ( Map.Entry<Integer, String> entry : paragraphs.entrySet() )
{
public void dumpParagraphs( boolean dumpAssotiatedPapx ) {
for ( Map.Entry<Integer, String> entry : paragraphs.entrySet() ) {
Integer endOfParagraphCharOffset = entry.getKey();
System.out.println( "[...; " + ( endOfParagraphCharOffset + 1 )
+ "): " + entry.getValue() );
if ( dumpAssotiatedPapx )
{
if ( dumpAssotiatedPapx ) {
boolean hasAssotiatedPapx = false;
for ( PAPX papx : _doc.getParagraphTable().getParagraphs() )
{
for ( PAPX papx : _doc.getParagraphTable().getParagraphs() ) {
if ( papx.getStart() <= endOfParagraphCharOffset.intValue()
&& endOfParagraphCharOffset.intValue() < papx
.getEnd() )
{
.getEnd() ) {
hasAssotiatedPapx = true;
System.out.println( "* " + papx );
@ -603,8 +529,7 @@ public final class HWPFLister
dumpSprms( sprmIt, "** " );
}
}
if ( !hasAssotiatedPapx )
{
if ( !hasAssotiatedPapx ) {
System.out.println( "* "
+ "NO PAPX ASSOTIATED WITH PARAGRAPH!" );
}
@ -612,20 +537,16 @@ public final class HWPFLister
}
}
protected void dumpSprms( SprmIterator sprmIt, String linePrefix )
{
while ( sprmIt.hasNext() )
{
protected void dumpSprms( SprmIterator sprmIt, String linePrefix ) {
while ( sprmIt.hasNext() ) {
SprmOperation sprm = sprmIt.next();
System.out.println( linePrefix + sprm);
}
}
public void dumpParagraphsDom( boolean withText )
{
public void dumpParagraphsDom( boolean withText ) {
Range range = _doc.getOverallRange();
for ( int p = 0; p < range.numParagraphs(); p++ )
{
for ( int p = 0; p < range.numParagraphs(); p++ ) {
Paragraph paragraph = range.getParagraph( p );
System.out.println( p + ":\t" + paragraph);
@ -634,33 +555,27 @@ public final class HWPFLister
}
}
private void dumpPictures()
{
if ( _doc instanceof HWPFOldDocument )
{
private void dumpPictures() {
if ( _doc instanceof HWPFOldDocument ) {
System.out.println( "Word 95 not supported so far" );
return;
}
List<Picture> allPictures = ( (HWPFDocument) _doc ).getPicturesTable()
.getAllPictures();
for ( Picture picture : allPictures )
{
for ( Picture picture : allPictures ) {
System.out.println(picture);
}
}
private void dumpStyles()
{
if ( _doc instanceof HWPFOldDocument )
{
private void dumpStyles() {
if ( _doc instanceof HWPFOldDocument ) {
System.out.println( "Word 95 not supported so far" );
return;
}
HWPFDocument hwpfDocument = (HWPFDocument) _doc;
for ( int s = 0; s < hwpfDocument.getStyleSheet().numStyles(); s++ )
{
for ( int s = 0; s < hwpfDocument.getStyleSheet().numStyles(); s++ ) {
StyleDescription styleDescription = hwpfDocument.getStyleSheet()
.getStyleDescription( s );
if ( styleDescription == null )
@ -681,32 +596,27 @@ public final class HWPFLister
}
protected void dumpParagraphLevels( ListTables listTables,
ParagraphProperties paragraph )
{
if ( paragraph.getIlfo() != 0 )
{
ParagraphProperties paragraph ) {
if ( paragraph.getIlfo() != 0 ) {
final LFO lfo = listTables.getLfo( paragraph.getIlfo() );
System.out.println( "PAP's LFO: " + lfo );
final LFOData lfoData = listTables.getLfoData( paragraph.getIlfo() );
System.out.println( "PAP's LFOData: " + lfoData );
if ( lfo != null )
{
if ( lfo != null ) {
final ListLevel listLevel = listTables.getLevel( lfo.getLsid(),
paragraph.getIlvl() );
System.out.println( "PAP's ListLevel: " + listLevel );
if ( listLevel.getGrpprlPapx() != null )
{
if ( listLevel.getGrpprlPapx() != null ) {
System.out.println( "PAP's ListLevel PAPX:" );
dumpSprms(
new SprmIterator( listLevel.getGrpprlPapx(), 0 ),
"* " );
}
if ( listLevel.getGrpprlPapx() != null )
{
if ( listLevel.getGrpprlPapx() != null ) {
System.out.println( "PAP's ListLevel CHPX:" );
dumpSprms(
new SprmIterator( listLevel.getGrpprlChpx(), 0 ),
@ -716,14 +626,11 @@ public final class HWPFLister
}
}
public void dumpTextPieces( boolean withText )
{
for ( TextPiece textPiece : _doc.getTextTable().getTextPieces() )
{
public void dumpTextPieces( boolean withText ) {
for ( TextPiece textPiece : _doc.getTextTable().getTextPieces() ) {
System.out.println( textPiece );
if ( withText )
{
if ( withText ) {
System.out.println( "\t" + textPiece.getStringBuilder() );
}
}

View File

@ -31,22 +31,18 @@ import org.apache.poi.util.Internal;
* v20110608 Word (.doc) Binary File Format
*/
@Internal
public class FibBase extends FibBaseAbstractType
{
public class FibBase extends FibBaseAbstractType {
public FibBase()
{
public FibBase() {
}
public FibBase( byte[] std, int offset )
{
public FibBase( byte[] std, int offset ) {
fillFields( std, offset );
}
@Override
@SuppressWarnings( "deprecation" )
public boolean equals( Object obj )
{
public boolean equals( Object obj ) {
if ( this == obj )
return true;
if ( obj == null )
@ -87,8 +83,7 @@ public class FibBase extends FibBaseAbstractType
@Override
@SuppressWarnings( "deprecation" )
public int hashCode()
{
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + field_10_flags2;
@ -107,5 +102,4 @@ public class FibBase extends FibBaseAbstractType
result = prime * result + field_9_envr;
return result;
}
}

View File

@ -286,4 +286,35 @@ public class TestVBAMacroReader {
assertContains(content, "Attribute VB_Customizable = True");
r.close();
}
@Test
public void bug62624() throws IOException {
//macro comes from Common Crawl: HRLOXHGMGLFIJQQU27RIWXOARRHAAAAS
File f = POIDataSamples.getSpreadSheetInstance().getFile("62624.bin");
VBAMacroReader r = new VBAMacroReader(f);
Map<String, Module> macros = r.readMacroModules();
assertEquals(13, macros.size());
assertNotNull(macros.get("M\u00F3dulo1"));
assertContains(macros.get("M\u00F3dulo1").getContent(), "Calcula_tributos");
assertEquals(Module.ModuleType.Module, macros.get("M\u00F3dulo1").geModuleType());
r.close();
}
@Test
public void bug62625() throws IOException {
//macro comes from Common Crawl: 4BZ22N5QG5R2SUU2MNN47PO7VBQLNYIQ
//A REFERENCE_NAME can sometimes only have an ascii string without
//a reserved byte followed by the unicode string.
//See https://github.com/decalage2/oletools/blob/master/oletools/olevba.py#L1516
//and https://github.com/decalage2/oletools/pull/135 from (@c1fe)
File f = POIDataSamples.getSpreadSheetInstance().getFile("62625.bin");
VBAMacroReader r = new VBAMacroReader(f);
Map<String, Module> macros = r.readMacroModules();
assertEquals(20, macros.size());
r.close();
}
}

View File

@ -41,6 +41,7 @@ import org.junit.runners.Suite;
TestQuotientFunctionsFromSpreadsheet.class,
TestReptFunctionsFromSpreadsheet.class,
TestRomanFunctionsFromSpreadsheet.class,
TestTrendFunctionsFromSpreadsheet.class,
TestWeekNumFunctionsFromSpreadsheet.class,
TestWeekNumFunctionsFromSpreadsheet2013.class
})

View File

@ -0,0 +1,91 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.ss.formula.functions;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.junit.Test;
import static org.apache.poi.ss.formula.functions.Frequency.histogram;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
/**
* Testcase for the function FREQUENCY(data, bins)
*
* @author Yegor Kozlov
*/
public class TestFrequency {
@Test
public void testHistogram() {
assertArrayEquals(new int[]{3, 2, 2, 0, 1, 1},
histogram(
new double[]{11, 12, 13, 21, 29, 36, 40, 58, 69},
new double[]{20, 30, 40, 50, 60})
);
assertArrayEquals(new int[]{1, 1, 1, 1, 1, 0},
histogram(
new double[]{20, 30, 40, 50, 60},
new double[]{20, 30, 40, 50, 60})
);
assertArrayEquals(new int[]{2, 3},
histogram(
new double[]{20, 30, 40, 50, 60},
new double[]{30})
);
}
@Test
public void testEvaluate() {
Workbook wb = new HSSFWorkbook();
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
int[] data = {1, 1, 2, 3, 4, 4, 5, 7, 8, 9, 9, 11, 3, 5, 8};
int[] bins = {3, 6, 9};
Sheet sheet = wb.createSheet();
Row dataRow = sheet.createRow(0); // A1:O1
for (int i = 0; i < data.length; i++) {
dataRow.createCell(i).setCellValue(data[i]);
}
Row binsRow = sheet.createRow(1);
for (int i = 0; i < bins.length; i++) { // A2:C2
binsRow.createCell(i).setCellValue(bins[i]);
}
Row fmlaRow = sheet.createRow(2);
CellRange<? extends Cell> arrayFmla = sheet.setArrayFormula("FREQUENCY(A1:O1,A2:C2)", CellRangeAddress.valueOf("A3:A6"));
Cell b3 = fmlaRow.createCell(1); // B3
b3.setCellFormula("COUNT(FREQUENCY(A1:O1,A2:C2))"); // frequency returns a vertical array of bins+1
Cell c3 = fmlaRow.createCell(2);
c3.setCellFormula("SUM(FREQUENCY(A1:O1,A2:C2))"); // sum of the frequency bins should add up to the number of data values
assertEquals(5, (int) evaluator.evaluate(arrayFmla.getFlattenedCells()[0]).getNumberValue());
assertEquals(4, (int) evaluator.evaluate(arrayFmla.getFlattenedCells()[1]).getNumberValue());
assertEquals(5, (int) evaluator.evaluate(arrayFmla.getFlattenedCells()[2]).getNumberValue());
assertEquals(1, (int) evaluator.evaluate(arrayFmla.getFlattenedCells()[3]).getNumberValue());
assertEquals(4, (int) evaluator.evaluate(b3).getNumberValue());
assertEquals(15, (int) evaluator.evaluate(c3).getNumberValue());
}
}

View File

@ -0,0 +1,31 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.ss.formula.functions;
import java.util.Collection;
import org.junit.runners.Parameterized.Parameters;
/**
* Tests TREND() as loaded from a test data spreadsheet.
*/
public class TestTrendFunctionsFromSpreadsheet extends BaseTestFunctionsFromSpreadsheet {
@Parameters(name="{0}")
public static Collection<Object[]> data() throws Exception {
return data(TestTrendFunctionsFromSpreadsheet.class, "Trend.xls");
}
}

View File

@ -99,15 +99,6 @@ public final class TestDateFormatConverter {
row.createCell(5).setCellValue(javaDateFormatPattern);
row.createCell(6).setCellValue(excelFormatPattern);
} catch (Exception e) {
// this can be removed after https://bugs.openjdk.java.net/browse/JDK-8209047 is available
// in JDK 11 ea > 26
if(locale.toString().startsWith("my") &&
e.getMessage().contains("Illegal pattern character 'B'") &&
System.getProperty("java.version").startsWith("11")) {
System.out.println("DateFormat.getDateTimeInstance() fails for Malaysian Locale on JDK 11, submitted bug report to Oracle");
continue;
}
throw new RuntimeException(
"Failed for locale: " + locale + " and style " + style + "\n" +
"Having locales: " + Arrays.toString(DateFormat.getAvailableLocales()), e);
@ -153,7 +144,6 @@ public final class TestDateFormatConverter {
DateFormatConverter.getPrefixForLocale(new Locale(""));
}
@Ignore("Fails on JDK 11, submitted as ID : 9056763")
@Test
public void testJDK11MyLocale() {
DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.forLanguageTag("my"));

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,284 @@
RkNumber
10000000
1200455
0.01
12004.55
-10000000
-1200455
-0.01
-12004.55
10268609
1071427521
-1071427521
273214017855
69942788570880
17905353874145300
17835411085574400
273214017855
273214017856
273214017857
273214017858
273214017859
273214017860
273214017861
273214017862
273214017863
273214017864
273214017865
273214017866
273214017867
273214017868
273214017869
273214017870
273214017871
273214017872
273214017873
273214017874
273214017875
273214017876
273214017877
273214017878
273214017879
273214017880
273214017881
273214017882
273214017883
273214017884
273214017885
273214017886
273214017887
273214017888
273214017889
273214017890
273214017891
273214017892
273214017893
273214017894
273214017895
273214017896
273214017897
273214017898
273214017899
273214017900
273214017901
273214017902
273214017903
273214017904
273214017905
273214017906
273214017907
273214017908
273214017909
273214017910
273214017911
273214017912
273214017913
273214017914
273214017915
273214017916
273214017917
273214017918
273214017919
273214017920
273214017921
273214017922
273214017923
273214017924
273214017925
273214017926
273214017927
273214017928
273214017929
273214017930
273214017931
273214017932
273214017933
273214017934
273214017935
273214017936
273214017937
273214017938
273214017939
273214017940
273214017941
273214017942
273214017943
273214017944
273214017945
273214017946
273214017947
273214017948
273214017949
273214017950
273214017951
273214017952
273214017953
273214017954
273214017955
273214017956
273214017957
273214017958
273214017959
273214017960
273214017961
273214017962
273214017963
273214017964
273214017965
273214017966
273214017967
273214017968
273214017969
273214017970
273214017971
273214017972
273214017973
273214017974
273214017975
273214017976
273214017977
273214017978
273214017979
273214017980
273214017981
273214017982
273214017983
273214017984
273214017985
273214017986
273214017987
273214017988
273214017989
273214017990
273214017991
273214017992
273214017993
273214017994
273214017995
273214017996
273214017997
273214017998
273214017999
273214018000
273214018001
273214018002
273214018003
273214018004
273214018005
273214018006
273214018007
273214018008
273214018009
273214018010
273214018011
273214018012
273214018013
273214018014
273214018015
273214018016
273214018017
273214018018
273214018019
273214018020
273214018021
273214018022
273214018023
273214018024
273214018025
273214018026
273214018027
273214018028
273214018029
273214018030
273214018031
273214018032
273214018033
273214018034
273214018035
273214018036
273214018037
273214018038
273214018039
273214018040
273214018041
273214018042
273214018043
273214018044
273214018045
273214018046
273214018047
273214018048
273214018049
273214018050
273214018051
273214018052
273214018053
273214018054
273214018055
273214018056
273214018057
273214018058
273214018059
273214018060
273214018061
273214018062
273214018063
273214018064
273214018065
273214018066
273214018067
273214018068
273214018069
273214018070
273214018071
273214018072
273214018073
273214018074
273214018075
273214018076
273214018077
273214018078
273214018079
273214018080
273214018081
273214018082
273214018083
273214018084
273214018085
273214018086
273214018087
273214018088
273214018089
273214018090
273214018091
273214018092
273214018093
273214018094
273214018095
273214018096
273214018097
273214018098
273214018099
273214018100
273214018101
273214018102
273214018103
273214018104
273214018105
273214018106
273214018107
273214018108
273214018109
273214018110
273214018111
273214018112
273214018113
273214018114
273214018115
910713.3937166670
3.03571131238889
0.000010119037707963000
3.37E-11
1.12E-16
#excel doesn't display ...863, this was manually altered to get the test to work
3.7477917436899863E-22

Binary file not shown.

Binary file not shown.