diff options
10 files changed, 1072 insertions, 1255 deletions
diff --git a/src/java/org/apache/poi/ss/util/DateFormatConverter.java b/src/java/org/apache/poi/ss/util/DateFormatConverter.java index deb4050daf..e338e8485c 100644 --- a/src/java/org/apache/poi/ss/util/DateFormatConverter.java +++ b/src/java/org/apache/poi/ss/util/DateFormatConverter.java @@ -133,28 +133,30 @@ public final class DateFormatConverter { result.put( "S", "0" ); result.put( "SS", "00" ); result.put( "SSS", "000" ); + result.put( "y", "yyyy" ); return result; } public static String getPrefixForLocale( Locale locale ) { final String languageTag = locale.toLanguageTag(); - if ("".equals(languageTag)) { + if (Locale.ROOT.equals(locale) || "".equals(languageTag)) { // JDK 8 adds an empty locale-string, see also https://issues.apache.org/jira/browse/LANG-941 - return "[$-0409]"; + return ""; } LocaleID loc = LocaleID.lookupByLanguageTag(languageTag); if (loc == null) { - String cmpTag = (languageTag.indexOf('_') > -1) ? languageTag.replace('_','-') : languageTag; + String cmpTag = (languageTag.indexOf('_') > -1) ? languageTag.replace('_', '-') : languageTag; int idx = languageTag.length(); - while (loc == null && (idx = cmpTag.lastIndexOf('-', idx-1)) > 0) { + while (loc == null && (idx = cmpTag.lastIndexOf('-', idx - 1)) > 0) { loc = LocaleID.lookupByLanguageTag(languageTag.substring(0, idx)); } - if (loc == null) { - LOG.log( POILogger.ERROR, "Unable to find prefix for Locale '", languageTag, "' or its parent locales." ); - return ""; - } + } + + if (loc == null) { + LOG.log(POILogger.ERROR, "Unable to find prefix for Locale '", languageTag, "' or its parent locales."); + return ""; } return String.format(Locale.ROOT, "[$-%04X]", loc.getLcid()); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java index 19d0bbb2b4..0792ddc655 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFName.java @@ -17,20 +17,19 @@ package org.apache.poi.xssf.usermodel; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; import java.util.Arrays; import org.apache.poi.ss.usermodel.BaseTestNamedRange; import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.XSSFITestDataProvider; +import org.apache.poi.xssf.XSSFTestDataSamples; import org.junit.jupiter.api.Test; -/** - * @author Yegor Kozlov - */ public final class TestXSSFName extends BaseTestNamedRange { public TestXSSFName() { diff --git a/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java b/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java index b6b56c8bca..741ee21c47 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java @@ -56,124 +56,108 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; @Beta -public abstract class AbstractWordConverter -{ - private static class DeadFieldBoundaries - { +public abstract class AbstractWordConverter { + private static class DeadFieldBoundaries { final int beginMark; final int endMark; final int separatorMark; - public DeadFieldBoundaries( int beginMark, int separatorMark, - int endMark ) - { + public DeadFieldBoundaries(int beginMark, int separatorMark, + int endMark) { this.beginMark = beginMark; this.separatorMark = separatorMark; this.endMark = endMark; } } - private static final class Structure implements Comparable<Structure> - { + private static final class Structure implements Comparable<Structure> { final int end; final int start; final Object structure; - Structure( Bookmark bookmark ) - { + Structure(Bookmark bookmark) { this.start = bookmark.getStart(); this.end = bookmark.getEnd(); this.structure = bookmark; } - Structure( DeadFieldBoundaries deadFieldBoundaries, int start, int end ) - { + Structure(DeadFieldBoundaries deadFieldBoundaries, int start, int end) { this.start = start; this.end = end; this.structure = deadFieldBoundaries; } - Structure( Field field ) - { + Structure(Field field) { this.start = field.getFieldStartOffset(); this.end = field.getFieldEndOffset(); this.structure = field; } - public int compareTo( Structure o ) - { + public int compareTo(Structure o) { return Integer.compare(start, o.start); } @Override - public String toString() - { + public String toString() { return "Structure [" + start + "; " + end + "): " - + structure; + + structure; } } private static final byte BEL_MARK = 7; private static final byte FIELD_BEGIN_MARK = 19; - private static final byte FIELD_END_MARK = 21; - private static final byte FIELD_SEPARATOR_MARK = 20; + private static final int FIELD_PAGE_REFERENCE = 37; + private static final int FIELD_EMBEDDED_OBJECT = 58; + private static final int FIELD_DROP_DOWN = 83; + private static final int FIELD_HYPERLINK = 88; - private static final POILogger LOG = POILogFactory.getLogger( AbstractWordConverter.class ); + + private static final POILogger LOG = POILogFactory.getLogger(AbstractWordConverter.class); private static final Pattern PATTERN_HYPERLINK_EXTERNAL = Pattern - .compile( "^[ \\t\\r\\n]*HYPERLINK \"(.*)\".*$" ); + .compile("^[ \\t\\r\\n]*HYPERLINK \"(.*)\".*$"); private static final Pattern PATTERN_HYPERLINK_LOCAL = Pattern - .compile( "^[ \\t\\r\\n]*HYPERLINK \\\\l \"(.*)\"[ ](.*)$" ); + .compile("^[ \\t\\r\\n]*HYPERLINK \\\\l \"(.*)\"[ ](.*)$"); private static final Pattern PATTERN_PAGEREF = Pattern - .compile( "^[ \\t\\r\\n]*PAGEREF ([^ ]*)[ \\t\\r\\n]*\\\\h.*$" ); + .compile("^[ \\t\\r\\n]*PAGEREF ([^ ]*)[ \\t\\r\\n]*\\\\h.*$"); private static final byte SPECCHAR_AUTONUMBERED_FOOTNOTE_REFERENCE = 2; - private static final byte SPECCHAR_DRAWN_OBJECT = 8; protected static final char UNICODECHAR_NO_BREAK_SPACE = '\u00a0'; - protected static final char UNICODECHAR_NONBREAKING_HYPHEN = '\u2011'; - protected static final char UNICODECHAR_ZERO_WIDTH_SPACE = '\u200b'; - private static void addToStructures( List<Structure> structures, - Structure structure ) - { - for ( Iterator<Structure> iterator = structures.iterator(); iterator - .hasNext(); ) - { + private static void addToStructures(List<Structure> structures, + Structure structure) { + for (Iterator<Structure> iterator = structures.iterator(); iterator + .hasNext(); ) { Structure another = iterator.next(); - if ( another.start <= structure.start - && another.end >= structure.start ) - { + if (another.start <= structure.start + && another.end >= structure.start) { return; } - if ( ( structure.start < another.start && another.start < structure.end ) - || ( structure.start < another.start && another.end <= structure.end ) - || ( structure.start <= another.start && another.end < structure.end ) ) - { + if ((structure.start < another.start && another.start < structure.end) + || (structure.start < another.start && another.end <= structure.end) + || (structure.start <= another.start && another.end < structure.end)) { iterator.remove(); - continue; } } - structures.add( structure ); + structures.add(structure); } private final Set<Bookmark> bookmarkStack = new LinkedHashSet<>(); private FontReplacer fontReplacer = new DefaultFontReplacer(); - private POILogger log = POILogFactory.getLogger( getClass() ); - - private NumberingState numberingState = new NumberingState(); + private final NumberingState numberingState = new NumberingState(); private PicturesManager picturesManager; @@ -182,116 +166,107 @@ public abstract class AbstractWordConverter * updating stylesheets or building document notes list. Usually they are * called once, but it's okay to call them several times. */ - protected void afterProcess() - { + protected void afterProcess() { // by default no such actions needed } - protected Triplet getCharacterRunTriplet(CharacterRun characterRun ) - { + protected Triplet getCharacterRunTriplet(CharacterRun characterRun) { Triplet original = new Triplet(); original.bold = characterRun.isBold(); original.italic = characterRun.isItalic(); original.fontName = characterRun.getFontName(); - return getFontReplacer().update( original ); + return getFontReplacer().update(original); } public abstract Document getDocument(); - public FontReplacer getFontReplacer() - { + public FontReplacer getFontReplacer() { return fontReplacer; } - protected int getNumberColumnsSpanned( int[] tableCellEdges, - int currentEdgeIndex, TableCell tableCell ) - { + protected int getNumberColumnsSpanned(int[] tableCellEdges, + int currentEdgeIndex, TableCell tableCell) { int nextEdgeIndex = currentEdgeIndex; int colSpan = 0; int cellRightEdge = tableCell.getLeftEdge() + tableCell.getWidth(); - while ( tableCellEdges[nextEdgeIndex] < cellRightEdge ) - { + while (tableCellEdges[nextEdgeIndex] < cellRightEdge) { colSpan++; nextEdgeIndex++; } return colSpan; } - protected int getNumberRowsSpanned( Table table, - final int[] tableCellEdges, int currentRowIndex, - int currentColumnIndex, TableCell tableCell ) - { - if ( !tableCell.isFirstVerticallyMerged() ) + protected int getNumberRowsSpanned(Table table, + final int[] tableCellEdges, int currentRowIndex, + int currentColumnIndex, TableCell tableCell) { + if (!tableCell.isFirstVerticallyMerged()) { return 1; + } final int numRows = table.numRows(); int count = 1; - for ( int r1 = currentRowIndex + 1; r1 < numRows; r1++ ) - { - TableRow nextRow = table.getRow( r1 ); - if ( currentColumnIndex >= nextRow.numCells() ) + for (int r1 = currentRowIndex + 1; r1 < numRows; r1++) { + TableRow nextRow = table.getRow(r1); + if (currentColumnIndex >= nextRow.numCells()) { break; + } // we need to skip row if he don't have cells at all boolean hasCells = false; int currentEdgeIndex = 0; - for ( int c = 0; c < nextRow.numCells(); c++ ) - { - TableCell nextTableCell = nextRow.getCell( c ); - if ( !nextTableCell.isVerticallyMerged() - || nextTableCell.isFirstVerticallyMerged() ) - { - int colSpan = getNumberColumnsSpanned( tableCellEdges, - currentEdgeIndex, nextTableCell ); + for (int c = 0; c < nextRow.numCells(); c++) { + TableCell nextTableCell = nextRow.getCell(c); + if (!nextTableCell.isVerticallyMerged() + || nextTableCell.isFirstVerticallyMerged()) { + int colSpan = getNumberColumnsSpanned(tableCellEdges, + currentEdgeIndex, nextTableCell); currentEdgeIndex += colSpan; - if ( colSpan != 0 ) - { + if (colSpan != 0) { hasCells = true; break; } - } - else - { + } else { currentEdgeIndex += getNumberColumnsSpanned( - tableCellEdges, currentEdgeIndex, nextTableCell ); + tableCellEdges, currentEdgeIndex, nextTableCell); } } - if ( !hasCells ) + if (!hasCells) { continue; + } - TableCell nextCell = nextRow.getCell( currentColumnIndex ); - if ( !nextCell.isVerticallyMerged() - || nextCell.isFirstVerticallyMerged() ) + TableCell nextCell = nextRow.getCell(currentColumnIndex); + if (!nextCell.isVerticallyMerged() + || nextCell.isFirstVerticallyMerged()) { break; + } count++; } return count; } - public PicturesManager getPicturesManager() - { + public PicturesManager getPicturesManager() { return picturesManager; } - protected abstract void outputCharacters( Element block, - CharacterRun characterRun, String text ); + protected abstract void outputCharacters(Element block, + CharacterRun characterRun, String text); /** * Wrap range into bookmark(s) and process it. All bookmarks have starts * equal to range start and ends equal to range end. Usually it's only one * bookmark. */ - protected abstract void processBookmarks( HWPFDocumentCore wordDocument, - Element currentBlock, Range range, int currentTableLevel, - List<Bookmark> rangeBookmarks ); - - protected boolean processCharacters( final HWPFDocumentCore wordDocument, - final int currentTableLevel, final Range range, final Element block ) - { - if ( range == null ) + protected abstract void processBookmarks(HWPFDocumentCore wordDocument, + Element currentBlock, Range range, int currentTableLevel, + List<Bookmark> rangeBookmarks); + + protected boolean processCharacters(final HWPFDocumentCore wordDocument, + final int currentTableLevel, final Range range, final Element block) { + if (range == null) { return false; + } boolean haveAnyText = false; @@ -302,62 +277,57 @@ public abstract class AbstractWordConverter * reconstruct the structure of range -- sergey */ List<Structure> structures = new LinkedList<>(); - if ( wordDocument instanceof HWPFDocument ) - { + if (wordDocument instanceof HWPFDocument) { final HWPFDocument doc = (HWPFDocument) wordDocument; Map<Integer, List<Bookmark>> rangeBookmarks = doc.getBookmarks() - .getBookmarksStartedBetween( range.getStartOffset(), - range.getEndOffset() ); - - if ( rangeBookmarks != null ) - { - for ( List<Bookmark> lists : rangeBookmarks.values() ) - { - for ( Bookmark bookmark : lists ) - { - if ( !bookmarkStack.contains( bookmark ) ) - addToStructures( structures, new Structure( - bookmark ) ); + .getBookmarksStartedBetween(range.getStartOffset(), + range.getEndOffset()); + + if (rangeBookmarks != null) { + for (List<Bookmark> lists : rangeBookmarks.values()) { + for (Bookmark bookmark : lists) { + if (!bookmarkStack.contains(bookmark)) { + addToStructures(structures, new Structure( + bookmark)); + } } } } // TODO: dead fields? int skipUntil = -1; - for ( int c = 0; c < range.numCharacterRuns(); c++ ) - { - CharacterRun characterRun = range.getCharacterRun( c ); - if ( characterRun == null ) + for (int c = 0; c < range.numCharacterRuns(); c++) { + CharacterRun characterRun = range.getCharacterRun(c); + if (characterRun == null) { throw new AssertionError(); - if ( characterRun.getStartOffset() < skipUntil ) + } + if (characterRun.getStartOffset() < skipUntil) { continue; + } String text = characterRun.text(); - if ( text == null || text.length() == 0 - || text.charAt( 0 ) != FIELD_BEGIN_MARK ) + if (text == null || text.length() == 0 + || text.charAt(0) != FIELD_BEGIN_MARK) { continue; - - Field aliveField = ( (HWPFDocument) wordDocument ).getFields() - .getFieldByStartOffset( FieldsDocumentPart.MAIN, - characterRun.getStartOffset() ); - if ( aliveField != null ) - { - addToStructures( structures, new Structure( aliveField ) ); } - else - { + + Field aliveField = ((HWPFDocument) wordDocument).getFields() + .getFieldByStartOffset(FieldsDocumentPart.MAIN, + characterRun.getStartOffset()); + if (aliveField != null) { + addToStructures(structures, new Structure(aliveField)); + } else { int[] separatorEnd = tryDeadField_lookupFieldSeparatorEnd( - wordDocument, range, c ); - if ( separatorEnd != null ) - { + range, c); + if (separatorEnd != null) { addToStructures( - structures, - new Structure( new DeadFieldBoundaries( c, - separatorEnd[0], separatorEnd[1] ), - characterRun.getStartOffset(), range - .getCharacterRun( - separatorEnd[1] ) - .getEndOffset() ) ); + structures, + new Structure(new DeadFieldBoundaries(c, + separatorEnd[0], separatorEnd[1]), + characterRun.getStartOffset(), range + .getCharacterRun( + separatorEnd[1]) + .getEndOffset())); c = separatorEnd[1]; } } @@ -365,261 +335,221 @@ public abstract class AbstractWordConverter } structures = new ArrayList<>(structures); - Collections.sort( structures ); + Collections.sort(structures); int previous = range.getStartOffset(); - for ( Structure structure : structures ) - { - if ( structure.start != previous ) - { - Range subrange = new Range( previous, structure.start, range ) - { + for (Structure structure : structures) { + if (structure.start != previous) { + Range subrange = new Range(previous, structure.start, range) { @Override - public String toString() - { + public String toString() { return "BetweenStructuresSubrange " + super.toString(); } }; - processCharacters( wordDocument, currentTableLevel, subrange, - block ); + processCharacters(wordDocument, currentTableLevel, subrange, + block); } - if ( structure.structure instanceof Bookmark ) - { + if (structure.structure instanceof Bookmark) { + assert(wordDocument instanceof HWPFDocument); // other bookmarks with same boundaries List<Bookmark> bookmarks = new LinkedList<>(); - for ( Bookmark bookmark : ( (HWPFDocument) wordDocument ) - .getBookmarks() - .getBookmarksStartedBetween( structure.start, - structure.start + 1 ).values().iterator() - .next() ) - { - if ( bookmark.getStart() == structure.start - && bookmark.getEnd() == structure.end ) - { - bookmarks.add( bookmark ); + for (Bookmark bookmark : ((HWPFDocument) wordDocument) + .getBookmarks() + .getBookmarksStartedBetween(structure.start, + structure.start + 1).values().iterator() + .next()) { + if (bookmark.getStart() == structure.start + && bookmark.getEnd() == structure.end) { + bookmarks.add(bookmark); } } - bookmarkStack.addAll( bookmarks ); - try - { - int end = Math.min( range.getEndOffset(), structure.end ); - Range subrange = new Range( structure.start, end, range ) - { + bookmarkStack.addAll(bookmarks); + try { + int end = Math.min(range.getEndOffset(), structure.end); + Range subrange = new Range(structure.start, end, range) { @Override - public String toString() - { + public String toString() { return "BookmarksSubrange " + super.toString(); } }; - processBookmarks( wordDocument, block, subrange, - currentTableLevel, bookmarks ); + processBookmarks(wordDocument, block, subrange, + currentTableLevel, bookmarks); + } finally { + bookmarkStack.removeAll(bookmarks); } - finally - { - bookmarkStack.removeAll( bookmarks ); - } - } - else if ( structure.structure instanceof Field ) - { + } else if (structure.structure instanceof Field) { + assert(wordDocument instanceof HWPFDocument); Field field = (Field) structure.structure; - processField( (HWPFDocument) wordDocument, range, - currentTableLevel, field, block ); - } - else if ( structure.structure instanceof DeadFieldBoundaries ) - { + processField((HWPFDocument) wordDocument, range, currentTableLevel, field, block); + } else if (structure.structure instanceof DeadFieldBoundaries) { DeadFieldBoundaries boundaries = (DeadFieldBoundaries) structure.structure; - processDeadField( wordDocument, block, range, - currentTableLevel, boundaries.beginMark, - boundaries.separatorMark, boundaries.endMark ); - } - else - { - throw new UnsupportedOperationException( "NYI: " - + structure.structure.getClass() ); + processDeadField(wordDocument, block, range, + currentTableLevel, boundaries.beginMark, + boundaries.separatorMark, boundaries.endMark); + } else { + throw new UnsupportedOperationException("NYI: " + + structure.structure.getClass()); } - previous = Math.min( range.getEndOffset(), structure.end ); + previous = Math.min(range.getEndOffset(), structure.end); } - if ( previous != range.getStartOffset() ) - { - if ( previous > range.getEndOffset() ) - { - LOG.log( POILogger.WARN, "Latest structure in ", range, - " ended at #", previous, " after range boundaries [", - range.getStartOffset(), "; ", range.getEndOffset(), - ")" ); + if (previous != range.getStartOffset()) { + if (previous > range.getEndOffset()) { + LOG.log(POILogger.WARN, "Latest structure in ", range, + " ended at #", previous, " after range boundaries [", + range.getStartOffset(), "; ", range.getEndOffset(), + ")"); return true; } - if ( previous < range.getEndOffset() ) - { - Range subrange = new Range( previous, range.getEndOffset(), - range ) - { + if (previous < range.getEndOffset()) { + Range subrange = new Range(previous, range.getEndOffset(), + range) { @Override - public String toString() - { + public String toString() { return "AfterStructureSubrange " + super.toString(); } }; - processCharacters( wordDocument, currentTableLevel, subrange, - block ); + processCharacters(wordDocument, currentTableLevel, subrange, + block); } return true; } - for ( int c = 0; c < range.numCharacterRuns(); c++ ) - { - CharacterRun characterRun = range.getCharacterRun( c ); + for (int c = 0; c < range.numCharacterRuns(); c++) { + CharacterRun characterRun = range.getCharacterRun(c); - if ( characterRun == null ) + if (characterRun == null) { throw new AssertionError(); + } - if ( wordDocument instanceof HWPFDocument - && ( (HWPFDocument) wordDocument ).getPicturesTable() - .hasPicture( characterRun ) ) - { + if (wordDocument instanceof HWPFDocument + && ((HWPFDocument) wordDocument).getPicturesTable() + .hasPicture(characterRun)) { HWPFDocument newFormat = (HWPFDocument) wordDocument; Picture picture = newFormat.getPicturesTable().extractPicture( - characterRun, true ); + characterRun, true); - processImage( block, characterRun.text().charAt( 0 ) == 0x01, - picture ); + processImage(block, characterRun.text().charAt(0) == 0x01, + picture); continue; } String text = characterRun.text(); - if ( text.isEmpty() ) continue; + if (text.isEmpty()) { + continue; + } - if ( characterRun.isSpecialCharacter() ) - { - if ( text.charAt( 0 ) == SPECCHAR_AUTONUMBERED_FOOTNOTE_REFERENCE - && ( wordDocument instanceof HWPFDocument ) ) - { + if (characterRun.isSpecialCharacter()) { + if (text.charAt(0) == SPECCHAR_AUTONUMBERED_FOOTNOTE_REFERENCE + && (wordDocument instanceof HWPFDocument)) { HWPFDocument doc = (HWPFDocument) wordDocument; - processNoteAnchor( doc, characterRun, block ); + processNoteAnchor(doc, characterRun, block); continue; } - if ( text.charAt( 0 ) == SPECCHAR_DRAWN_OBJECT - && ( wordDocument instanceof HWPFDocument ) ) - { + if (text.charAt(0) == SPECCHAR_DRAWN_OBJECT + && (wordDocument instanceof HWPFDocument)) { HWPFDocument doc = (HWPFDocument) wordDocument; - processDrawnObject( doc, characterRun, block ); + processDrawnObject(doc, characterRun, block); continue; } - if ( characterRun.isOle2() - && ( wordDocument instanceof HWPFDocument ) ) - { + if (characterRun.isOle2() + && (wordDocument instanceof HWPFDocument)) { HWPFDocument doc = (HWPFDocument) wordDocument; - processOle2( doc, characterRun, block ); + processOle2(doc, characterRun, block); continue; } - if ( characterRun.isSymbol() - && ( wordDocument instanceof HWPFDocument ) ) - { + if (characterRun.isSymbol() + && (wordDocument instanceof HWPFDocument)) { HWPFDocument doc = (HWPFDocument) wordDocument; - processSymbol( doc, characterRun, block ); + processSymbol(doc, characterRun, block); continue; } } - if ( text.charAt(0) == FIELD_BEGIN_MARK ) - { - if ( wordDocument instanceof HWPFDocument ) - { - Field aliveField = ( (HWPFDocument) wordDocument ) - .getFields().getFieldByStartOffset( - FieldsDocumentPart.MAIN, - characterRun.getStartOffset() ); - if ( aliveField != null ) - { - processField( ( (HWPFDocument) wordDocument ), range, - currentTableLevel, aliveField, block ); + if (text.charAt(0) == FIELD_BEGIN_MARK) { + if (wordDocument instanceof HWPFDocument) { + Field aliveField = ((HWPFDocument) wordDocument) + .getFields().getFieldByStartOffset( + FieldsDocumentPart.MAIN, + characterRun.getStartOffset()); + if (aliveField != null) { + processField(((HWPFDocument) wordDocument), range, + currentTableLevel, aliveField, block); int continueAfter = aliveField.getFieldEndOffset(); - while ( c < range.numCharacterRuns() - && range.getCharacterRun( c ).getEndOffset() <= continueAfter ) + while (c < range.numCharacterRuns() + && range.getCharacterRun(c).getEndOffset() <= continueAfter) { c++; + } - if ( c < range.numCharacterRuns() ) + if (c < range.numCharacterRuns()) { c--; + } continue; } } - int skipTo = tryDeadField( wordDocument, range, - currentTableLevel, c, block ); + int skipTo = tryDeadField(wordDocument, range, + currentTableLevel, c, block); - if ( skipTo != c ) - { + if (skipTo != c) { c = skipTo; continue; } continue; } - if ( text.charAt(0) == FIELD_SEPARATOR_MARK ) - { + if (text.charAt(0) == FIELD_SEPARATOR_MARK) { // shall not appear without FIELD_BEGIN_MARK continue; } - if ( text.charAt(0) == FIELD_END_MARK ) - { + if (text.charAt(0) == FIELD_END_MARK) { // shall not appear without FIELD_BEGIN_MARK continue; } - if ( characterRun.isSpecialCharacter() || characterRun.isObj() - || characterRun.isOle2() ) - { + if (characterRun.isSpecialCharacter() || characterRun.isObj() + || characterRun.isOle2()) { continue; } - if ( text.endsWith( "\r" ) - || ( text.charAt( text.length() - 1 ) == BEL_MARK && currentTableLevel != Integer.MIN_VALUE ) ) - text = text.substring( 0, text.length() - 1 ); + if (text.endsWith("\r") + || (text.charAt(text.length() - 1) == BEL_MARK && currentTableLevel != Integer.MIN_VALUE)) { + text = text.substring(0, text.length() - 1); + } { // line breaks StringBuilder stringBuilder = new StringBuilder(); - for ( char charChar : text.toCharArray() ) - { - if ( charChar == 11 ) - { - if ( stringBuilder.length() > 0 ) - { - outputCharacters( block, characterRun, - stringBuilder.toString() ); - stringBuilder.setLength( 0 ); + for (char charChar : text.toCharArray()) { + if (charChar == 11) { + if (stringBuilder.length() > 0) { + outputCharacters(block, characterRun, + stringBuilder.toString()); + stringBuilder.setLength(0); } - processLineBreak( block, characterRun ); - } - else if ( charChar == 30 ) - { + processLineBreak(block, characterRun); + } else if (charChar == 30) { // Non-breaking hyphens are stored as ASCII 30 - stringBuilder.append( UNICODECHAR_NONBREAKING_HYPHEN ); - } - else if ( charChar == 31 ) - { + stringBuilder.append(UNICODECHAR_NONBREAKING_HYPHEN); + } else if (charChar == 31) { // Non-required hyphens to zero-width space - stringBuilder.append( UNICODECHAR_ZERO_WIDTH_SPACE ); - } - else if ( charChar >= 0x20 || charChar == 0x09 - || charChar == 0x0A || charChar == 0x0D ) - { - stringBuilder.append( charChar ); + stringBuilder.append(UNICODECHAR_ZERO_WIDTH_SPACE); + } else if (charChar >= 0x20 || charChar == 0x09 + || charChar == 0x0A || charChar == 0x0D) { + stringBuilder.append(charChar); } } - if ( stringBuilder.length() > 0 ) - { - outputCharacters( block, characterRun, - stringBuilder.toString() ); - stringBuilder.setLength( 0 ); + if (stringBuilder.length() > 0) { + outputCharacters(block, characterRun, + stringBuilder.toString()); + stringBuilder.setLength(0); } } @@ -629,291 +559,253 @@ public abstract class AbstractWordConverter return haveAnyText; } - protected void processDeadField( HWPFDocumentCore wordDocument, - Element currentBlock, Range range, int currentTableLevel, - int beginMark, int separatorMark, int endMark ) - { - if ( beginMark + 1 < separatorMark && separatorMark + 1 < endMark ) - { - Range formulaRange = new Range( range.getCharacterRun( - beginMark + 1 ).getStartOffset(), range.getCharacterRun( - separatorMark - 1 ).getEndOffset(), range ) - { + protected void processDeadField(HWPFDocumentCore wordDocument, + Element currentBlock, Range range, int currentTableLevel, + int beginMark, int separatorMark, int endMark) { + if (beginMark + 1 < separatorMark && separatorMark + 1 < endMark) { + Range formulaRange = new Range(range.getCharacterRun( + beginMark + 1).getStartOffset(), range.getCharacterRun( + separatorMark - 1).getEndOffset(), range) { @Override - public String toString() - { + public String toString() { return "Dead field formula subrange: " + super.toString(); } }; - Range valueRange = new Range( range.getCharacterRun( - separatorMark + 1 ).getStartOffset(), range - .getCharacterRun( endMark - 1 ).getEndOffset(), range ) - { + Range valueRange = new Range(range.getCharacterRun( + separatorMark + 1).getStartOffset(), range + .getCharacterRun(endMark - 1).getEndOffset(), range) { @Override - public String toString() - { + public String toString() { return "Dead field value subrange: " + super.toString(); } }; String formula = formulaRange.text(); - final Matcher matcher = PATTERN_HYPERLINK_LOCAL.matcher( formula ); - if ( matcher.matches() ) - { - String localref = matcher.group( 1 ); - processPageref( wordDocument, currentBlock, valueRange, - currentTableLevel, localref ); + final Matcher matcher = PATTERN_HYPERLINK_LOCAL.matcher(formula); + if (matcher.matches()) { + String localref = matcher.group(1); + processPageref(wordDocument, currentBlock, valueRange, + currentTableLevel, localref); return; } } - StringBuilder debug = new StringBuilder( "Unsupported field type: \n" ); - for ( int i = beginMark; i <= endMark; i++ ) - { - debug.append( "\t" ); - debug.append( range.getCharacterRun( i ) ); - debug.append( "\n" ); + StringBuilder debug = new StringBuilder("Unsupported field type: \n"); + for (int i = beginMark; i <= endMark; i++) { + debug.append("\t"); + debug.append(range.getCharacterRun(i)); + debug.append("\n"); } - LOG.log( POILogger.WARN, debug ); + LOG.log(POILogger.WARN, debug); - Range deadFieldValueSubrage = new Range( range.getCharacterRun( - separatorMark ).getStartOffset() + 1, range.getCharacterRun( - endMark ).getStartOffset(), range ) - { + Range deadFieldValueSubrage = new Range(range.getCharacterRun( + separatorMark).getStartOffset() + 1, range.getCharacterRun( + endMark).getStartOffset(), range) { @Override - public String toString() - { + public String toString() { return "DeadFieldValueSubrange (" + super.toString() + ")"; } }; // just output field value - if ( separatorMark + 1 < endMark ) - processCharacters( wordDocument, currentTableLevel, - deadFieldValueSubrage, currentBlock ); + if (separatorMark + 1 < endMark) { + processCharacters(wordDocument, currentTableLevel, + deadFieldValueSubrage, currentBlock); + } } - public void processDocument( HWPFDocumentCore wordDocument ) - { - try - { + public void processDocument(HWPFDocumentCore wordDocument) { + try { final SummaryInformation summaryInformation = wordDocument - .getSummaryInformation(); - if ( summaryInformation != null ) - { - processDocumentInformation( summaryInformation ); + .getSummaryInformation(); + if (summaryInformation != null) { + processDocumentInformation(summaryInformation); } - } - catch ( Exception exc ) - { - LOG.log( POILogger.WARN, - "Unable to process document summary information: ", exc, - exc ); + } catch (Exception exc) { + LOG.log(POILogger.WARN, "Unable to process document summary information: ", exc, exc); } final Range docRange = wordDocument.getRange(); - if ( docRange.numSections() == 1 ) - { - processSingleSection( wordDocument, docRange.getSection( 0 ) ); + if (docRange.numSections() == 1) { + processSingleSection(wordDocument, docRange.getSection(0)); afterProcess(); return; } - processDocumentPart( wordDocument, docRange ); + processDocumentPart(wordDocument, docRange); afterProcess(); } protected abstract void processDocumentInformation( - SummaryInformation summaryInformation ); + SummaryInformation summaryInformation); - protected void processDocumentPart( HWPFDocumentCore wordDocument, - final Range range ) - { - for ( int s = 0; s < range.numSections(); s++ ) - { - processSection( wordDocument, range.getSection( s ), s ); + protected void processDocumentPart(HWPFDocumentCore wordDocument, + final Range range) { + for (int s = 0; s < range.numSections(); s++) { + processSection(wordDocument, range.getSection(s), s); } } - protected void processDrawnObject( HWPFDocument doc, - CharacterRun characterRun, Element block ) - { - if ( getPicturesManager() == null ) + protected void processDrawnObject(HWPFDocument doc, + CharacterRun characterRun, Element block) { + if (getPicturesManager() == null) { return; + } // TODO: support headers OfficeDrawing officeDrawing = doc.getOfficeDrawingsMain() - .getOfficeDrawingAt( characterRun.getStartOffset() ); - if ( officeDrawing == null ) - { - LOG.log( POILogger.WARN, "Characters #", characterRun, - " references missing drawn object" ); + .getOfficeDrawingAt(characterRun.getStartOffset()); + if (officeDrawing == null) { + LOG.log(POILogger.WARN, "Characters #", characterRun, + " references missing drawn object"); return; } byte[] pictureData = officeDrawing.getPictureData(); - if ( pictureData == null ) - // usual shape? + if (pictureData == null) + // usual shape? + { return; + } - float width = ( officeDrawing.getRectangleRight() - officeDrawing - .getRectangleLeft() ) / AbstractWordUtils.TWIPS_PER_INCH; - float height = ( officeDrawing.getRectangleBottom() - officeDrawing - .getRectangleTop() ) / AbstractWordUtils.TWIPS_PER_INCH; + float width = (officeDrawing.getRectangleRight() - officeDrawing + .getRectangleLeft()) / AbstractWordUtils.TWIPS_PER_INCH; + float height = (officeDrawing.getRectangleBottom() - officeDrawing + .getRectangleTop()) / AbstractWordUtils.TWIPS_PER_INCH; - final PictureType type = PictureType.findMatchingType( pictureData ); + final PictureType type = PictureType.findMatchingType(pictureData); String path = getPicturesManager() - .savePicture( pictureData, type, - "s" + characterRun.getStartOffset() + "." + type, - width, height ); + .savePicture(pictureData, type, + "s" + characterRun.getStartOffset() + "." + type, + width, height); - processDrawnObject( doc, characterRun, officeDrawing, path, block ); + processDrawnObject(doc, characterRun, officeDrawing, path, block); } - protected abstract void processDrawnObject( HWPFDocument doc, - CharacterRun characterRun, OfficeDrawing officeDrawing, - String path, Element block ); + protected abstract void processDrawnObject(HWPFDocument doc, + CharacterRun characterRun, OfficeDrawing officeDrawing, + String path, Element block); - protected void processDropDownList( Element block, - CharacterRun characterRun, String[] values, int defaultIndex ) - { - outputCharacters( block, characterRun, values[defaultIndex] ); + protected void processDropDownList(Element block, + CharacterRun characterRun, String[] values, int defaultIndex) { + outputCharacters(block, characterRun, values[defaultIndex]); } protected abstract void processEndnoteAutonumbered( - HWPFDocument wordDocument, int noteIndex, Element block, - Range endnoteTextRange ); - - protected void processField( HWPFDocument wordDocument, Range parentRange, - int currentTableLevel, Field field, Element currentBlock ) - { - switch ( field.getType() ) - { - case 37: // page reference - { - final Range firstSubrange = field.firstSubrange( parentRange ); - if ( firstSubrange != null ) - { - String formula = firstSubrange.text(); - Matcher matcher = PATTERN_PAGEREF.matcher( formula ); - if ( matcher.find() ) - { - String pageref = matcher.group( 1 ); - processPageref( wordDocument, currentBlock, - field.secondSubrange( parentRange ), - currentTableLevel, pageref ); - return; + HWPFDocument wordDocument, int noteIndex, Element block, + Range endnoteTextRange); + + protected void processField(HWPFDocument wordDocument, Range parentRange, + int currentTableLevel, Field field, Element currentBlock) { + switch (field.getType()) { + case FIELD_PAGE_REFERENCE: { + final Range firstSubrange = field.firstSubrange(parentRange); + if (firstSubrange != null) { + String formula = firstSubrange.text(); + Matcher matcher = PATTERN_PAGEREF.matcher(formula); + if (matcher.find()) { + String pageref = matcher.group(1); + processPageref(wordDocument, currentBlock, + field.secondSubrange(parentRange), + currentTableLevel, pageref); + return; + } } + break; } - break; - } - case 58: // Embedded Object - { - if ( !field.hasSeparator() ) - { - LOG.log( POILogger.WARN, parentRange, " contains ", field, - " with 'Embedded Object' but without separator mark" ); - return; - } + case FIELD_EMBEDDED_OBJECT: { + if (!field.hasSeparator()) { + LOG.log(POILogger.WARN, parentRange, " contains ", field, + " with 'Embedded Object' but without separator mark"); + return; + } - CharacterRun separator = field - .getMarkSeparatorCharacterRun( parentRange ); + CharacterRun separator = field + .getMarkSeparatorCharacterRun(parentRange); - if ( separator.isOle2() ) - { - // the only supported so far - boolean processed = processOle2( wordDocument, separator, - currentBlock ); - - // if we didn't output OLE - output field value - if ( !processed ) - { - processCharacters( wordDocument, currentTableLevel, - field.secondSubrange( parentRange ), currentBlock ); - } + if (separator.isOle2()) { + // the only supported so far + boolean processed = processOle2(wordDocument, separator, + currentBlock); - return; - } + // if we didn't output OLE - output field value + if (!processed) { + processCharacters(wordDocument, currentTableLevel, + field.secondSubrange(parentRange), currentBlock); + } - break; - } - case 83: // drop down - { - Range fieldContent = field.firstSubrange( parentRange ); - CharacterRun cr = fieldContent.getCharacterRun( fieldContent - .numCharacterRuns() - 1 ); - String[] values = cr.getDropDownListValues(); - Integer defIndex = cr.getDropDownListDefaultItemIndex(); + return; + } - if ( values != null && values.length > 0 ) - { - processDropDownList( currentBlock, cr, values, - defIndex == null ? -1 : defIndex.intValue() ); - return; + break; } - break; - } - case 88: // hyperlink - { - final Range firstSubrange = field.firstSubrange( parentRange ); - if ( firstSubrange != null ) - { - String formula = firstSubrange.text(); - Matcher matcher = PATTERN_HYPERLINK_EXTERNAL.matcher( formula ); - if ( matcher.matches() ) - { - String hyperlink = matcher.group( 1 ); - processHyperlink( wordDocument, currentBlock, - field.secondSubrange( parentRange ), - currentTableLevel, hyperlink ); + case FIELD_DROP_DOWN: { + Range fieldContent = field.firstSubrange(parentRange); + CharacterRun cr = fieldContent.getCharacterRun(fieldContent + .numCharacterRuns() - 1); + String[] values = cr.getDropDownListValues(); + Integer defIndex = cr.getDropDownListDefaultItemIndex(); + + if (values != null && values.length > 0) { + processDropDownList(currentBlock, cr, values, + defIndex == null ? -1 : defIndex); return; } - matcher.usePattern( PATTERN_HYPERLINK_LOCAL ); - if ( matcher.matches() ) - { - String hyperlink = matcher.group( 1 ); - Range textRange = null; - String text = matcher.group( 2 ); - if ( AbstractWordUtils.isNotEmpty( text ) ) - { - textRange = new Range( firstSubrange.getStartOffset() - + matcher.start( 2 ), + break; + } + case FIELD_HYPERLINK: { + final Range firstSubrange = field.firstSubrange(parentRange); + if (firstSubrange != null) { + String formula = firstSubrange.text(); + Matcher matcher = PATTERN_HYPERLINK_EXTERNAL.matcher(formula); + if (matcher.matches()) { + String hyperlink = matcher.group(1); + processHyperlink(wordDocument, currentBlock, + field.secondSubrange(parentRange), + currentTableLevel, hyperlink); + return; + } + matcher.usePattern(PATTERN_HYPERLINK_LOCAL); + if (matcher.matches()) { + String hyperlink = matcher.group(1); + Range textRange = null; + String text = matcher.group(2); + if (AbstractWordUtils.isNotEmpty(text)) { + textRange = new Range(firstSubrange.getStartOffset() + + matcher.start(2), firstSubrange.getStartOffset() - + matcher.end( 2 ), firstSubrange ) - { - @Override - public String toString() - { - return "Local hyperlink text"; - } - }; + + matcher.end(2), firstSubrange) { + @Override + public String toString() { + return "Local hyperlink text"; + } + }; + } + processPageref(wordDocument, currentBlock, textRange, + currentTableLevel, hyperlink); + return; } - processPageref( wordDocument, currentBlock, textRange, - currentTableLevel, hyperlink ); - return; } + break; } - break; - } } - LOG.log( POILogger.WARN, parentRange, " contains ", field, - " with unsupported type or format" ); - processCharacters( wordDocument, currentTableLevel, - field.secondSubrange( parentRange ), currentBlock ); + LOG.log(POILogger.WARN, parentRange, " contains ", field, " with unsupported type or format"); + processCharacters(wordDocument, currentTableLevel, + field.secondSubrange(parentRange), currentBlock); } protected abstract void processFootnoteAutonumbered( - HWPFDocument wordDocument, int noteIndex, Element block, - Range footnoteTextRange ); + HWPFDocument wordDocument, int noteIndex, Element block, + Range footnoteTextRange); - protected abstract void processHyperlink( HWPFDocumentCore wordDocument, - Element currentBlock, Range textRange, int currentTableLevel, - String hyperlink ); + protected abstract void processHyperlink(HWPFDocumentCore wordDocument, + Element currentBlock, Range textRange, int currentTableLevel, + String hyperlink); - protected void processImage( Element currentBlock, boolean inlined, Picture picture ) { + protected void processImage(Element currentBlock, boolean inlined, Picture picture) { PicturesManager fileManager = getPicturesManager(); - if ( fileManager != null ) { + if (fileManager != null) { final float aspectRatioX = picture.getHorizontalScalingFactor(); final float aspectRatioY = picture.getVerticalScalingFactor(); @@ -929,259 +821,197 @@ public abstract class AbstractWordConverter } imageHeight /= AbstractWordUtils.TWIPS_PER_INCH; - String url = fileManager.savePicture( picture.getContent(), - picture.suggestPictureType(), - picture.suggestFullFileName(), imageWidth, imageHeight ); + String url = fileManager.savePicture(picture.getContent(), + picture.suggestPictureType(), + picture.suggestFullFileName(), imageWidth, imageHeight); - if ( AbstractWordUtils.isNotEmpty( url ) ) - { - processImage( currentBlock, inlined, picture, url ); + if (AbstractWordUtils.isNotEmpty(url)) { + processImage(currentBlock, inlined, picture, url); return; } } - processImageWithoutPicturesManager( currentBlock, inlined, picture ); + processImageWithoutPicturesManager(currentBlock, inlined, picture); } - protected abstract void processImage( Element currentBlock, - boolean inlined, Picture picture, String url ); + protected abstract void processImage(Element currentBlock, + boolean inlined, Picture picture, String url); @Internal protected abstract void processImageWithoutPicturesManager( - Element currentBlock, boolean inlined, Picture picture ); + Element currentBlock, boolean inlined, Picture picture); - protected abstract void processLineBreak( Element block, - CharacterRun characterRun ); + protected abstract void processLineBreak(Element block, CharacterRun characterRun); - protected void processNoteAnchor( HWPFDocument doc, - CharacterRun characterRun, final Element block ) - { - { - Notes footnotes = doc.getFootnotes(); - int noteIndex = footnotes - .getNoteIndexByAnchorPosition( characterRun - .getStartOffset() ); - if ( noteIndex != -1 ) - { - Range footnoteRange = doc.getFootnoteRange(); - int rangeStartOffset = footnoteRange.getStartOffset(); - int noteTextStartOffset = footnotes - .getNoteTextStartOffset( noteIndex ); - int noteTextEndOffset = footnotes - .getNoteTextEndOffset( noteIndex ); - - Range noteTextRange = new Range( rangeStartOffset - + noteTextStartOffset, rangeStartOffset - + noteTextEndOffset, doc ); - - processFootnoteAutonumbered( doc, noteIndex, block, - noteTextRange ); - return; - } + protected void processNoteAnchor(HWPFDocument doc, CharacterRun characterRun, final Element block) { + Notes footnotes = doc.getFootnotes(); + int footIndex = footnotes.getNoteIndexByAnchorPosition(characterRun.getStartOffset()); + if (footIndex != -1) { + Range footRange = doc.getFootnoteRange(); + int rangeStartOffset = footRange.getStartOffset(); + int noteTextStartOffset = footnotes.getNoteTextStartOffset(footIndex); + int noteTextEndOffset = footnotes.getNoteTextEndOffset(footIndex); + + Range noteTextRange = new Range(rangeStartOffset + + noteTextStartOffset, rangeStartOffset + + noteTextEndOffset, doc); + + processFootnoteAutonumbered(doc, footIndex, block, noteTextRange); + return; } - { - Notes endnotes = doc.getEndnotes(); - int noteIndex = endnotes.getNoteIndexByAnchorPosition( characterRun - .getStartOffset() ); - if ( noteIndex != -1 ) - { - Range endnoteRange = doc.getEndnoteRange(); - int rangeStartOffset = endnoteRange.getStartOffset(); - int noteTextStartOffset = endnotes - .getNoteTextStartOffset( noteIndex ); - int noteTextEndOffset = endnotes - .getNoteTextEndOffset( noteIndex ); - - Range noteTextRange = new Range( rangeStartOffset - + noteTextStartOffset, rangeStartOffset - + noteTextEndOffset, doc ); - - processEndnoteAutonumbered( doc, noteIndex, block, - noteTextRange ); - } + + Notes endnotes = doc.getEndnotes(); + int endIndex = endnotes.getNoteIndexByAnchorPosition(characterRun.getStartOffset()); + if (endIndex != -1) { + Range endnoteRange = doc.getEndnoteRange(); + int rangeStartOffset = endnoteRange.getStartOffset(); + int noteTextStartOffset = endnotes.getNoteTextStartOffset(endIndex); + int noteTextEndOffset = endnotes.getNoteTextEndOffset(endIndex); + + Range noteTextRange = new Range(rangeStartOffset + + noteTextStartOffset, rangeStartOffset + + noteTextEndOffset, doc); + + processEndnoteAutonumbered(doc, endIndex, block, noteTextRange); } } - private boolean processOle2( HWPFDocument doc, CharacterRun characterRun, - Element block ) - { - Entry entry = doc.getObjectsPool().getObjectById( - "_" + characterRun.getPicOffset() ); - if ( entry == null ) - { - LOG.log( POILogger.WARN, "Referenced OLE2 object '", - Integer.valueOf( characterRun.getPicOffset() ), - "' not found in ObjectPool" ); + private boolean processOle2(HWPFDocument doc, CharacterRun characterRun, + Element block) { + Entry entry = doc.getObjectsPool().getObjectById("_" + characterRun.getPicOffset()); + if (entry == null) { + LOG.log(POILogger.WARN, "Referenced OLE2 object '", characterRun.getPicOffset(), "' not found in ObjectPool"); return false; } - try - { - return processOle2( doc, block, entry ); - } - catch ( Exception exc ) - { - LOG.log( POILogger.WARN, - "Unable to convert internal OLE2 object '", - Integer.valueOf( characterRun.getPicOffset() ), "': ", exc, - exc ); + try { + return processOle2(doc, block, entry); + } catch (Exception exc) { + LOG.log(POILogger.WARN, "Unable to convert internal OLE2 object '", characterRun.getPicOffset(), "': ", exc, exc); return false; } } - protected boolean processOle2( HWPFDocument wordDocument, Element block, - Entry entry ) throws Exception - { + protected boolean processOle2(HWPFDocument wordDocument, Element block, Entry entry) throws Exception { return false; } - protected abstract void processPageBreak( HWPFDocumentCore wordDocument, - Element flow ); + protected abstract void processPageBreak(HWPFDocumentCore wordDocument, Element flow); - protected abstract void processPageref( HWPFDocumentCore wordDocument, - Element currentBlock, Range textRange, int currentTableLevel, - String pageref ); + protected abstract void processPageref(HWPFDocumentCore wordDocument, + Element currentBlock, Range textRange, int currentTableLevel, + String pageref); - protected abstract void processParagraph( HWPFDocumentCore wordDocument, - Element parentElement, int currentTableLevel, Paragraph paragraph, - String bulletText ); + protected abstract void processParagraph(HWPFDocumentCore wordDocument, + Element parentElement, int currentTableLevel, Paragraph paragraph, + String bulletText); - protected void processParagraphes( HWPFDocumentCore wordDocument, - Element flow, Range range, int currentTableLevel ) - { + protected void processParagraphes(HWPFDocumentCore wordDocument, Element flow, Range range, int currentTableLevel) { final int paragraphs = range.numParagraphs(); - for ( int p = 0; p < paragraphs; p++ ) - { - Paragraph paragraph = range.getParagraph( p ); + for (int p = 0; p < paragraphs; p++) { + Paragraph paragraph = range.getParagraph(p); + + if (paragraph.isInTable() + && paragraph.getTableLevel() != currentTableLevel) { + if (paragraph.getTableLevel() < currentTableLevel) { + throw new IllegalStateException("Trying to process table cell with higher level (" + + paragraph.getTableLevel() + ") than current table level (" + + currentTableLevel + ") as inner table part"); + } - if ( paragraph.isInTable() - && paragraph.getTableLevel() != currentTableLevel ) - { - if ( paragraph.getTableLevel() < currentTableLevel ) - throw new IllegalStateException( - "Trying to process table cell with higher level (" - + paragraph.getTableLevel() - + ") than current table level (" - + currentTableLevel - + ") as inner table part" ); - - Table table = range.getTable( paragraph ); - processTable( wordDocument, flow, table ); - - p += table.numParagraphs(); - p--; + Table table = range.getTable(paragraph); + processTable(wordDocument, flow, table); + + p += table.numParagraphs() - 1; continue; } - if ( paragraph.text().equals( "\u000c" ) ) - { - processPageBreak( wordDocument, flow ); + if (paragraph.text().equals("\u000c")) { + processPageBreak(wordDocument, flow); } boolean processed = false; - if ( paragraph.isInList() ) - { - try - { + if (paragraph.isInList()) { + try { HWPFList hwpfList = paragraph.getList(); String label = AbstractWordUtils.getBulletText( - numberingState, hwpfList, - (char) paragraph.getIlvl() ); + numberingState, hwpfList, + (char) paragraph.getIlvl()); - processParagraph( wordDocument, flow, currentTableLevel, - paragraph, label ); + processParagraph(wordDocument, flow, currentTableLevel, paragraph, label); processed = true; - } - catch ( Exception exc ) - { - log.log( - POILogger.WARN, - "Can't process paragraph as list entry, will be processed without list information", - exc ); + } catch (Exception exc) { + LOG.log(POILogger.WARN, "Can't process paragraph as list entry, will be processed without list information", exc); } } - if (!processed) - { - processParagraph( wordDocument, flow, currentTableLevel, - paragraph, AbstractWordUtils.EMPTY ); + if (!processed) { + processParagraph(wordDocument, flow, currentTableLevel, + paragraph, AbstractWordUtils.EMPTY); } } } - protected abstract void processSection( HWPFDocumentCore wordDocument, - Section section, int s ); + protected abstract void processSection(HWPFDocumentCore wordDocument, Section section, int s); - protected void processSingleSection( HWPFDocumentCore wordDocument, - Section section ) - { - processSection( wordDocument, section, 0 ); + protected void processSingleSection(HWPFDocumentCore wordDocument, Section section) { + processSection(wordDocument, section, 0); } - protected void processSymbol( HWPFDocument doc, CharacterRun characterRun, - Element block ) - { + protected void processSymbol(HWPFDocument doc, CharacterRun characterRun, Element block) { } - protected abstract void processTable( HWPFDocumentCore wordDocument, - Element flow, Table table ); + protected abstract void processTable(HWPFDocumentCore wordDocument, Element flow, Table table); - public void setFontReplacer( FontReplacer fontReplacer ) - { + public void setFontReplacer(FontReplacer fontReplacer) { this.fontReplacer = fontReplacer; } - public void setPicturesManager( PicturesManager fileManager ) - { + public void setPicturesManager(PicturesManager fileManager) { this.picturesManager = fileManager; } - protected int tryDeadField( HWPFDocumentCore wordDocument, Range range, - int currentTableLevel, int beginMark, Element currentBlock ) - { + protected int tryDeadField(HWPFDocumentCore wordDocument, Range range, + int currentTableLevel, int beginMark, Element currentBlock) { int[] separatorEnd = tryDeadField_lookupFieldSeparatorEnd( - wordDocument, range, beginMark ); - if ( separatorEnd == null ) + range, beginMark); + if (separatorEnd == null) { return beginMark; + } - processDeadField( wordDocument, currentBlock, range, currentTableLevel, - beginMark, separatorEnd[0], separatorEnd[1] ); + processDeadField(wordDocument, currentBlock, range, currentTableLevel, + beginMark, separatorEnd[0], separatorEnd[1]); return separatorEnd[1]; } - private int[] tryDeadField_lookupFieldSeparatorEnd( - HWPFDocumentCore wordDocument, Range range, int beginMark ) - { + private int[] tryDeadField_lookupFieldSeparatorEnd(Range range, int beginMark) { int separatorMark = -1; int endMark = -1; - for ( int c = beginMark + 1; c < range.numCharacterRuns(); c++ ) - { - CharacterRun characterRun = range.getCharacterRun( c ); + for (int c = beginMark + 1; c < range.numCharacterRuns(); c++) { + CharacterRun characterRun = range.getCharacterRun(c); String text = characterRun.text(); - if ( text.isEmpty() ) continue; + if (text.isEmpty()) { + continue; + } final char firstByte = text.charAt(0); - if ( firstByte == FIELD_BEGIN_MARK ) - { + if (firstByte == FIELD_BEGIN_MARK) { int[] nested = tryDeadField_lookupFieldSeparatorEnd( - wordDocument, range, c ); - if ( nested != null ) - { + range, c); + if (nested != null) { c = nested[1]; } continue; } - if ( firstByte == FIELD_SEPARATOR_MARK ) - { - if ( separatorMark != -1 ) - { + if (firstByte == FIELD_SEPARATOR_MARK) { + if (separatorMark != -1) { // double; incorrect format return null; } @@ -1190,23 +1020,17 @@ public abstract class AbstractWordConverter continue; } - if ( firstByte == FIELD_END_MARK ) - { - if ( endMark != -1 ) - { - // double; - return null; - } - + if (firstByte == FIELD_END_MARK) { endMark = c; break; } } - if ( separatorMark == -1 || endMark == -1 ) + if (separatorMark == -1 || endMark == -1) { return null; + } - return new int[] { separatorMark, endMark }; + return new int[]{separatorMark, endMark}; } } diff --git a/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamBugs.java b/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamBugs.java index f7cd422ddb..47f33d0a15 100644 --- a/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hdgf/streams/TestStreamBugs.java @@ -19,6 +19,7 @@ package org.apache.poi.hdgf.streams; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.IOException; import java.io.InputStream; @@ -60,7 +61,8 @@ public final class TestStreamBugs extends StreamTest { @Test void testGetTrailer() { Pointer trailerPointer = ptrFactory.createPointer(contents, 0x24); - Stream.createStream(trailerPointer, contents, chunkFactory, ptrFactory); + Stream s = Stream.createStream(trailerPointer, contents, chunkFactory, ptrFactory); + assertNotNull(s); } @SuppressWarnings("unused") diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java index 2ec30c4396..d8adc7c529 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java @@ -17,6 +17,7 @@ package org.apache.poi.ss.usermodel; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -1318,7 +1319,7 @@ public abstract class BaseTestBugzillaIssues { sheet.setRowGroupCollapsed(0, true); sheet.groupColumn(0, 0); - sheet.setColumnGroupCollapsed(0, true); + assertDoesNotThrow(() -> sheet.setColumnGroupCollapsed(0, true)); } } @@ -1328,7 +1329,7 @@ public abstract class BaseTestBugzillaIssues { void test58648() throws IOException { try (Workbook wb = _testDataProvider.createWorkbook()) { Cell cell = wb.createSheet().createRow(0).createCell(0); - cell.setCellFormula("((1 + 1) )"); + assertDoesNotThrow(() -> cell.setCellFormula("((1 + 1) )")); } } @@ -1441,9 +1442,11 @@ public abstract class BaseTestBugzillaIssues { return time() - startTimeMillis; } - @Disabled("bug 59393") @Test void bug59393_commentsCanHaveSameAnchor() throws IOException { + // only executed for HSSF currently + assumeTrue("xls".equals(_testDataProvider.getStandardFileNameExtension())); + try (Workbook wb = _testDataProvider.createWorkbook()) { Sheet sheet = wb.createSheet(); @@ -1473,14 +1476,13 @@ public abstract class BaseTestBugzillaIssues { Comment comment2 = drawing.createCellComment(anchor); RichTextString richTextString2 = helper.createRichTextString("comment2"); comment2.setString(richTextString2); - cell2.setCellComment(comment2); + assertDoesNotThrow(() -> cell2.setCellComment(comment2)); // anchor.setCol1(2); Comment comment3 = drawing.createCellComment(anchor); RichTextString richTextString3 = helper.createRichTextString("comment3"); comment3.setString(richTextString3); - cell3.setCellComment(comment3); - + assertDoesNotThrow(() -> cell3.setCellComment(comment3)); } } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java index 64a85c64ee..4d3954fa78 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestConditionalFormatting.java @@ -1221,7 +1221,8 @@ public abstract class BaseTestConditionalFormatting { CellRangeAddress.valueOf("C9:D30"), CellRangeAddress.valueOf("C7:C31") }; ConditionalFormattingRule rule = sheet.getSheetConditionalFormatting().createConditionalFormattingRule("$A$1>0"); - sheet.getSheetConditionalFormatting().addConditionalFormatting(ranges, rule); + int form = sheet.getSheetConditionalFormatting().addConditionalFormatting(ranges, rule); + assertEquals(0, form); } } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestDataValidation.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestDataValidation.java index d1d70c6131..ccfd8293c0 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestDataValidation.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestDataValidation.java @@ -17,14 +17,14 @@ package org.apache.poi.ss.usermodel; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.usermodel.DataValidation.ErrorStyle; import org.apache.poi.ss.usermodel.DataValidationConstraint.OperatorType; import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddressList; -import org.apache.poi.util.POILogFactory; -import org.apache.poi.util.POILogger; import org.junit.jupiter.api.Test; /** @@ -35,472 +35,458 @@ import org.junit.jupiter.api.Test; public abstract class BaseTestDataValidation { private final ITestDataProvider _testDataProvider; - private static final POILogger log = POILogFactory.getLogger(BaseTestDataValidation.class); - protected BaseTestDataValidation(ITestDataProvider testDataProvider) { _testDataProvider = testDataProvider; } - /** Convenient access to ERROR_STYLE constants */ - protected static final DataValidation.ErrorStyle ES = null; - /** Convenient access to OPERATOR constants */ - protected static final DataValidationConstraint.ValidationType VT = null; - /** Convenient access to OPERATOR constants */ - protected static final DataValidationConstraint.OperatorType OP = null; - - private static final class ValidationAdder { - - private final CellStyle _style_1; - private final CellStyle _style_2; - private final int _validationType; - private final Sheet _sheet; - private int _currentRowIndex; - private final CellStyle _cellStyle; - - public ValidationAdder(Sheet fSheet, CellStyle style_1, CellStyle style_2, - CellStyle cellStyle, int validationType) { - _sheet = fSheet; - _style_1 = style_1; - _style_2 = style_2; - _cellStyle = cellStyle; - _validationType = validationType; - _currentRowIndex = fSheet.getPhysicalNumberOfRows(); - } - void addValidation(int operatorType, String firstFormula, String secondFormula, - int errorStyle, String ruleDescr, String promptDescr, - boolean allowEmpty, boolean inputBox, boolean errorBox) { - String[] explicitListValues = null; - - addValidationInternal(operatorType, firstFormula, secondFormula, errorStyle, ruleDescr, - promptDescr, allowEmpty, inputBox, errorBox, true, - explicitListValues); - } - - private void addValidationInternal(int operatorType, String firstFormula, - String secondFormula, int errorStyle, String ruleDescr, String promptDescr, - boolean allowEmpty, boolean inputBox, boolean errorBox, boolean suppressDropDown, - String[] explicitListValues) { - int rowNum = _currentRowIndex++; - - DataValidationHelper dataValidationHelper = _sheet.getDataValidationHelper(); - DataValidationConstraint dc = createConstraint(dataValidationHelper,operatorType, firstFormula, secondFormula, explicitListValues); - - DataValidation dv = dataValidationHelper.createValidation(dc,new CellRangeAddressList(rowNum, rowNum, 0, 0)); - - dv.setEmptyCellAllowed(allowEmpty); - dv.setErrorStyle(errorStyle); - dv.createErrorBox("Invalid Input", "Something is wrong - check condition!"); - dv.createPromptBox("Validated Cell", "Allowable values have been restricted"); - - dv.setShowPromptBox(inputBox); - dv.setShowErrorBox(errorBox); - dv.setSuppressDropDownArrow(suppressDropDown); - - - _sheet.addValidationData(dv); - writeDataValidationSettings(_sheet, _style_1, _style_2, ruleDescr, allowEmpty, - inputBox, errorBox); - if (_cellStyle != null) { - Row row = _sheet.getRow(_sheet.getPhysicalNumberOfRows() - 1); - Cell cell = row.createCell(0); - cell.setCellStyle(_cellStyle); - } - writeOtherSettings(_sheet, _style_1, promptDescr); - } - private DataValidationConstraint createConstraint(DataValidationHelper dataValidationHelper,int operatorType, String firstFormula, - String secondFormula, String[] explicitListValues) { - if (_validationType == ValidationType.LIST) { - if (explicitListValues != null) { - return dataValidationHelper.createExplicitListConstraint(explicitListValues); - } - return dataValidationHelper.createFormulaListConstraint(firstFormula); - } - if (_validationType == ValidationType.TIME) { - return dataValidationHelper.createTimeConstraint(operatorType, firstFormula, secondFormula); - } - if (_validationType == ValidationType.DATE) { - return dataValidationHelper.createDateConstraint(operatorType, firstFormula, secondFormula, null); - } - if (_validationType == ValidationType.FORMULA) { - return dataValidationHelper.createCustomConstraint(firstFormula); - } - - if( _validationType == ValidationType.INTEGER) { - return dataValidationHelper.createIntegerConstraint(operatorType, firstFormula, secondFormula); - } - if( _validationType == ValidationType.DECIMAL) { - return dataValidationHelper.createDecimalConstraint(operatorType, firstFormula, secondFormula); - } - if( _validationType == ValidationType.TEXT_LENGTH) { - return dataValidationHelper.createTextLengthConstraint(operatorType, firstFormula, secondFormula); - } - return null; - } - /** - * writes plain text values into cells in a tabular format to form comments readable from within - * the spreadsheet. - */ - private static void writeDataValidationSettings(Sheet sheet, CellStyle style_1, - CellStyle style_2, String strCondition, boolean allowEmpty, boolean inputBox, - boolean errorBox) { - Row row = sheet.createRow(sheet.getPhysicalNumberOfRows()); - // condition's string - Cell cell = row.createCell(1); - cell.setCellStyle(style_1); - setCellValue(cell, strCondition); - // allow empty cells - cell = row.createCell(2); - cell.setCellStyle(style_2); - setCellValue(cell, ((allowEmpty) ? "yes" : "no")); - // show input box - cell = row.createCell(3); - cell.setCellStyle(style_2); - setCellValue(cell, ((inputBox) ? "yes" : "no")); - // show error box - cell = row.createCell(4); - cell.setCellStyle(style_2); - setCellValue(cell, ((errorBox) ? "yes" : "no")); - } - private static void writeOtherSettings(Sheet sheet, CellStyle style, - String strStettings) { - Row row = sheet.getRow(sheet.getPhysicalNumberOfRows() - 1); - Cell cell = row.createCell(5); - cell.setCellStyle(style); - setCellValue(cell, strStettings); - } - void addListValidation(String[] explicitListValues, String listFormula, String listValsDescr, - boolean allowEmpty, boolean suppressDropDown) { - String promptDescr = (allowEmpty ? "empty ok" : "not empty") - + ", " + (suppressDropDown ? "no drop-down" : "drop-down"); - addValidationInternal(ValidationType.LIST, listFormula, null, ErrorStyle.STOP, listValsDescr, promptDescr, - allowEmpty, false, true, suppressDropDown, explicitListValues); - } - } - - private static void log(String msg) { - log.log(POILogger.INFO, msg); + /** + * Convenient access to ERROR_STYLE constants + */ + protected static final DataValidation.ErrorStyle ES = null; + /** + * Convenient access to OPERATOR constants + */ + protected static final DataValidationConstraint.ValidationType VT = null; + + private static final class ValidationAdder { + + private final CellStyle _style_1; + private final CellStyle _style_2; + private final int _validationType; + private final Sheet _sheet; + private int _currentRowIndex; + private final CellStyle _cellStyle; + + public ValidationAdder(Sheet fSheet, CellStyle style_1, CellStyle style_2, + CellStyle cellStyle, int validationType) { + _sheet = fSheet; + _style_1 = style_1; + _style_2 = style_2; + _cellStyle = cellStyle; + _validationType = validationType; + _currentRowIndex = fSheet.getPhysicalNumberOfRows(); + } + + void addValidation(int operatorType, String firstFormula, String secondFormula, + int errorStyle, String ruleDescr, String promptDescr, + boolean allowEmpty, boolean inputBox, boolean errorBox) { + String[] explicitListValues = null; + + addValidationInternal(operatorType, firstFormula, secondFormula, errorStyle, ruleDescr, + promptDescr, allowEmpty, inputBox, errorBox, true, + explicitListValues); + } + + private void addValidationInternal(int operatorType, String firstFormula, + String secondFormula, int errorStyle, String ruleDescr, String promptDescr, + boolean allowEmpty, boolean inputBox, boolean errorBox, boolean suppressDropDown, + String[] explicitListValues) { + int rowNum = _currentRowIndex++; + + DataValidationHelper dataValidationHelper = _sheet.getDataValidationHelper(); + DataValidationConstraint dc = createConstraint(dataValidationHelper, operatorType, firstFormula, secondFormula, explicitListValues); + + DataValidation dv = dataValidationHelper.createValidation(dc, new CellRangeAddressList(rowNum, rowNum, 0, 0)); + + dv.setEmptyCellAllowed(allowEmpty); + dv.setErrorStyle(errorStyle); + dv.createErrorBox("Invalid Input", "Something is wrong - check condition!"); + dv.createPromptBox("Validated Cell", "Allowable values have been restricted"); + + dv.setShowPromptBox(inputBox); + dv.setShowErrorBox(errorBox); + dv.setSuppressDropDownArrow(suppressDropDown); + + + _sheet.addValidationData(dv); + writeDataValidationSettings(_sheet, _style_1, _style_2, ruleDescr, allowEmpty, + inputBox, errorBox); + if (_cellStyle != null) { + Row row = _sheet.getRow(_sheet.getPhysicalNumberOfRows() - 1); + Cell cell = row.createCell(0); + cell.setCellStyle(_cellStyle); + } + writeOtherSettings(_sheet, _style_1, promptDescr); + } + + private DataValidationConstraint createConstraint(DataValidationHelper dataValidationHelper, int operatorType, String firstFormula, + String secondFormula, String[] explicitListValues) { + if (_validationType == ValidationType.LIST) { + if (explicitListValues != null) { + return dataValidationHelper.createExplicitListConstraint(explicitListValues); + } + return dataValidationHelper.createFormulaListConstraint(firstFormula); + } + if (_validationType == ValidationType.TIME) { + return dataValidationHelper.createTimeConstraint(operatorType, firstFormula, secondFormula); + } + if (_validationType == ValidationType.DATE) { + return dataValidationHelper.createDateConstraint(operatorType, firstFormula, secondFormula, null); + } + if (_validationType == ValidationType.FORMULA) { + return dataValidationHelper.createCustomConstraint(firstFormula); + } + + if (_validationType == ValidationType.INTEGER) { + return dataValidationHelper.createIntegerConstraint(operatorType, firstFormula, secondFormula); + } + if (_validationType == ValidationType.DECIMAL) { + return dataValidationHelper.createDecimalConstraint(operatorType, firstFormula, secondFormula); + } + if (_validationType == ValidationType.TEXT_LENGTH) { + return dataValidationHelper.createTextLengthConstraint(operatorType, firstFormula, secondFormula); + } + return null; + } + + /** + * writes plain text values into cells in a tabular format to form comments readable from within + * the spreadsheet. + */ + private static void writeDataValidationSettings(Sheet sheet, CellStyle style_1, + CellStyle style_2, String strCondition, boolean allowEmpty, boolean inputBox, + boolean errorBox) { + Row row = sheet.createRow(sheet.getPhysicalNumberOfRows()); + // condition's string + Cell cell = row.createCell(1); + cell.setCellStyle(style_1); + setCellValue(cell, strCondition); + // allow empty cells + cell = row.createCell(2); + cell.setCellStyle(style_2); + setCellValue(cell, ((allowEmpty) ? "yes" : "no")); + // show input box + cell = row.createCell(3); + cell.setCellStyle(style_2); + setCellValue(cell, ((inputBox) ? "yes" : "no")); + // show error box + cell = row.createCell(4); + cell.setCellStyle(style_2); + setCellValue(cell, ((errorBox) ? "yes" : "no")); + } + + private static void writeOtherSettings(Sheet sheet, CellStyle style, + String strStettings) { + Row row = sheet.getRow(sheet.getPhysicalNumberOfRows() - 1); + Cell cell = row.createCell(5); + cell.setCellStyle(style); + setCellValue(cell, strStettings); + } + + void addListValidation(String[] explicitListValues, String listFormula, String listValsDescr, + boolean allowEmpty, boolean suppressDropDown) { + String promptDescr = (allowEmpty ? "empty ok" : "not empty") + + ", " + (suppressDropDown ? "no drop-down" : "drop-down"); + addValidationInternal(ValidationType.LIST, listFormula, null, ErrorStyle.STOP, listValsDescr, promptDescr, + allowEmpty, false, true, suppressDropDown, explicitListValues); + } + } + + /** + * Manages the cell styles used for formatting the output spreadsheet + */ + private static final class WorkbookFormatter { + + private final Workbook _wb; + private final CellStyle _style_1; + private final CellStyle _style_2; + private final CellStyle _style_3; + private final CellStyle _style_4; + private Sheet _currentSheet; + + public WorkbookFormatter(Workbook wb) { + _wb = wb; + _style_1 = createStyle(wb, HorizontalAlignment.LEFT); + _style_2 = createStyle(wb, HorizontalAlignment.CENTER); + _style_3 = createStyle(wb, HorizontalAlignment.CENTER, IndexedColors.GREY_25_PERCENT.getIndex(), true); + _style_4 = createHeaderStyle(wb); + } + + private static CellStyle createStyle(Workbook wb, HorizontalAlignment h_align, short color, + boolean bold) { + Font font = wb.createFont(); + if (bold) { + font.setBold(true); + } + + CellStyle cellStyle = wb.createCellStyle(); + cellStyle.setFont(font); + cellStyle.setFillForegroundColor(color); + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + cellStyle.setAlignment(h_align); + cellStyle.setBorderLeft(BorderStyle.THIN); + cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle.setBorderTop(BorderStyle.THIN); + cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle.setBorderRight(BorderStyle.THIN); + cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); + cellStyle.setBorderBottom(BorderStyle.THIN); + cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); + + return cellStyle; + } + + private static CellStyle createStyle(Workbook wb, HorizontalAlignment h_align) { + return createStyle(wb, h_align, IndexedColors.WHITE.getIndex(), false); + } + + private static CellStyle createHeaderStyle(Workbook wb) { + Font font = wb.createFont(); + font.setColor(IndexedColors.WHITE.getIndex()); + font.setBold(true); + + CellStyle cellStyle = wb.createCellStyle(); + cellStyle.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex()); + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + cellStyle.setAlignment(HorizontalAlignment.CENTER); + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + cellStyle.setBorderLeft(BorderStyle.THIN); + cellStyle.setLeftBorderColor(IndexedColors.WHITE.getIndex()); + cellStyle.setBorderTop(BorderStyle.THIN); + cellStyle.setTopBorderColor(IndexedColors.WHITE.getIndex()); + cellStyle.setBorderRight(BorderStyle.THIN); + cellStyle.setRightBorderColor(IndexedColors.WHITE.getIndex()); + cellStyle.setBorderBottom(BorderStyle.THIN); + cellStyle.setBottomBorderColor(IndexedColors.WHITE.getIndex()); + cellStyle.setFont(font); + return cellStyle; + } + + + public Sheet createSheet(String sheetName) { + _currentSheet = _wb.createSheet(sheetName); + return _currentSheet; + } + + void createDVTypeRow(String strTypeDescription) { + Sheet sheet = _currentSheet; + Row row = sheet.createRow(sheet.getPhysicalNumberOfRows()); + sheet.addMergedRegion(new CellRangeAddress(sheet.getPhysicalNumberOfRows() - 1, sheet.getPhysicalNumberOfRows() - 1, 0, 5)); + Cell cell = row.createCell(0); + setCellValue(cell, strTypeDescription); + cell.setCellStyle(_style_3); + row = sheet.createRow(sheet.getPhysicalNumberOfRows()); + } + + void createHeaderRow() { + Sheet sheet = _currentSheet; + Row row = sheet.createRow(sheet.getPhysicalNumberOfRows()); + row.setHeight((short) 400); + for (int i = 0; i < 6; i++) { + row.createCell(i).setCellStyle(_style_4); + if (i == 2 || i == 3 || i == 4) { + sheet.setColumnWidth(i, 3500); + } else if (i == 5) { + sheet.setColumnWidth(i, 10000); + } else { + sheet.setColumnWidth(i, 8000); + } + } + Cell cell = row.getCell(0); + setCellValue(cell, "Data validation cells"); + cell = row.getCell(1); + setCellValue(cell, "Condition"); + cell = row.getCell(2); + setCellValue(cell, "Allow blank"); + cell = row.getCell(3); + setCellValue(cell, "Prompt box"); + cell = row.getCell(4); + setCellValue(cell, "Error box"); + cell = row.getCell(5); + setCellValue(cell, "Other settings"); + } + + public ValidationAdder createValidationAdder(CellStyle cellStyle, int dataValidationType) { + return new ValidationAdder(_currentSheet, _style_1, _style_2, cellStyle, dataValidationType); + } + + void createDVDescriptionRow(String strTypeDescription) { + Sheet sheet = _currentSheet; + Row row = sheet.getRow(sheet.getPhysicalNumberOfRows() - 1); + sheet.addMergedRegion(new CellRangeAddress(sheet.getPhysicalNumberOfRows() - 1, sheet.getPhysicalNumberOfRows() - 1, 0, 5)); + Cell cell = row.createCell(0); + setCellValue(cell, strTypeDescription); + cell.setCellStyle(_style_3); + row = sheet.createRow(sheet.getPhysicalNumberOfRows()); + } + } + + + private void addCustomValidations(WorkbookFormatter wf) { + wf.createSheet("Custom"); + wf.createHeaderRow(); + + ValidationAdder va = wf.createValidationAdder(null, ValidationType.FORMULA); + va.addValidation(OperatorType.BETWEEN, "ISNUMBER($A2)", null, ErrorStyle.STOP, "ISNUMBER(A2)", "Error box type = STOP", true, true, true); + va.addValidation(OperatorType.BETWEEN, "IF(SUM(A2:A3)=5,TRUE,FALSE)", null, ErrorStyle.WARNING, "IF(SUM(A2:A3)=5,TRUE,FALSE)", "Error box type = WARNING", false, false, true); + } + + private static void addSimpleNumericValidations(WorkbookFormatter wf) { + // data validation's number types + wf.createSheet("Numbers"); + + // "Whole number" validation type + wf.createDVTypeRow("Whole number"); + wf.createHeaderRow(); + + ValidationAdder va = wf.createValidationAdder(null, ValidationType.INTEGER); + va.addValidation(OperatorType.BETWEEN, "2", "6", ErrorStyle.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); + va.addValidation(OperatorType.NOT_BETWEEN, "2", "6", ErrorStyle.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); + va.addValidation(OperatorType.EQUAL, "=3+2", null, ErrorStyle.WARNING, "Equal to (3+2)", "Error box type = WARNING", false, false, true); + va.addValidation(OperatorType.NOT_EQUAL, "3", null, ErrorStyle.WARNING, "Not equal to 3", "-", false, false, false); + va.addValidation(OperatorType.GREATER_THAN, "3", null, ErrorStyle.WARNING, "Greater than 3", "-", true, false, false); + va.addValidation(OperatorType.LESS_THAN, "3", null, ErrorStyle.WARNING, "Less than 3", "-", true, true, false); + va.addValidation(OperatorType.GREATER_OR_EQUAL, "4", null, ErrorStyle.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); + va.addValidation(OperatorType.LESS_OR_EQUAL, "4", null, ErrorStyle.STOP, "Less than or equal to 4", "-", false, true, false); + + // "Decimal" validation type + wf.createDVTypeRow("Decimal"); + wf.createHeaderRow(); + + va = wf.createValidationAdder(null, ValidationType.DECIMAL); + va.addValidation(OperatorType.BETWEEN, "2", "6", ErrorStyle.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); + va.addValidation(OperatorType.NOT_BETWEEN, "2", "6", ErrorStyle.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); + va.addValidation(OperatorType.EQUAL, "3", null, ErrorStyle.WARNING, "Equal to 3", "Error box type = WARNING", false, false, true); + va.addValidation(OperatorType.NOT_EQUAL, "3", null, ErrorStyle.WARNING, "Not equal to 3", "-", false, false, false); + va.addValidation(OperatorType.GREATER_THAN, "=12/6", null, ErrorStyle.WARNING, "Greater than (12/6)", "-", true, false, false); + va.addValidation(OperatorType.LESS_THAN, "3", null, ErrorStyle.WARNING, "Less than 3", "-", true, true, false); + va.addValidation(OperatorType.GREATER_OR_EQUAL, "4", null, ErrorStyle.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); + va.addValidation(OperatorType.LESS_OR_EQUAL, "4", null, ErrorStyle.STOP, "Less than or equal to 4", "-", false, true, false); } - /** - * Manages the cell styles used for formatting the output spreadsheet - */ - private static final class WorkbookFormatter { - - private final Workbook _wb; - private final CellStyle _style_1; - private final CellStyle _style_2; - private final CellStyle _style_3; - private final CellStyle _style_4; - private Sheet _currentSheet; - - public WorkbookFormatter(Workbook wb) { - _wb = wb; - _style_1 = createStyle( wb, HorizontalAlignment.LEFT ); - _style_2 = createStyle( wb, HorizontalAlignment.CENTER ); - _style_3 = createStyle( wb, HorizontalAlignment.CENTER, IndexedColors.GREY_25_PERCENT.getIndex(), true ); - _style_4 = createHeaderStyle(wb); - } - - private static CellStyle createStyle(Workbook wb, HorizontalAlignment h_align, short color, - boolean bold) { - Font font = wb.createFont(); - if (bold) { - font.setBold(true); - } - - CellStyle cellStyle = wb.createCellStyle(); - cellStyle.setFont(font); - cellStyle.setFillForegroundColor(color); - cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); - cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); - cellStyle.setAlignment(h_align); - cellStyle.setBorderLeft(BorderStyle.THIN); - cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); - cellStyle.setBorderTop(BorderStyle.THIN); - cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); - cellStyle.setBorderRight(BorderStyle.THIN); - cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); - cellStyle.setBorderBottom(BorderStyle.THIN); - cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); - - return cellStyle; - } - - private static CellStyle createStyle(Workbook wb, HorizontalAlignment h_align) { - return createStyle(wb, h_align, IndexedColors.WHITE.getIndex(), false); - } - private static CellStyle createHeaderStyle(Workbook wb) { - Font font = wb.createFont(); - font.setColor( IndexedColors.WHITE.getIndex() ); - font.setBold(true); - - CellStyle cellStyle = wb.createCellStyle(); - cellStyle.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex()); - cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); - cellStyle.setAlignment(HorizontalAlignment.CENTER); - cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); - cellStyle.setBorderLeft(BorderStyle.THIN); - cellStyle.setLeftBorderColor(IndexedColors.WHITE.getIndex()); - cellStyle.setBorderTop(BorderStyle.THIN); - cellStyle.setTopBorderColor(IndexedColors.WHITE.getIndex()); - cellStyle.setBorderRight(BorderStyle.THIN); - cellStyle.setRightBorderColor(IndexedColors.WHITE.getIndex()); - cellStyle.setBorderBottom(BorderStyle.THIN); - cellStyle.setBottomBorderColor(IndexedColors.WHITE.getIndex()); - cellStyle.setFont(font); - return cellStyle; - } - - - public Sheet createSheet(String sheetName) { - _currentSheet = _wb.createSheet(sheetName); - return _currentSheet; - } - void createDVTypeRow(String strTypeDescription) { - Sheet sheet = _currentSheet; - Row row = sheet.createRow(sheet.getPhysicalNumberOfRows()); - sheet.addMergedRegion(new CellRangeAddress(sheet.getPhysicalNumberOfRows()-1, sheet.getPhysicalNumberOfRows()-1, 0, 5)); - Cell cell = row.createCell(0); - setCellValue(cell, strTypeDescription); - cell.setCellStyle(_style_3); - row = sheet.createRow(sheet.getPhysicalNumberOfRows()); - } - - void createHeaderRow() { - Sheet sheet = _currentSheet; - Row row = sheet.createRow(sheet.getPhysicalNumberOfRows()); - row.setHeight((short) 400); - for (int i = 0; i < 6; i++) { - row.createCell(i).setCellStyle(_style_4); - if (i == 2 || i == 3 || i == 4) { - sheet.setColumnWidth(i, 3500); - } else if (i == 5) { - sheet.setColumnWidth(i, 10000); - } else { - sheet.setColumnWidth(i, 8000); - } - } - Cell cell = row.getCell(0); - setCellValue(cell, "Data validation cells"); - cell = row.getCell(1); - setCellValue(cell, "Condition"); - cell = row.getCell(2); - setCellValue(cell, "Allow blank"); - cell = row.getCell(3); - setCellValue(cell, "Prompt box"); - cell = row.getCell(4); - setCellValue(cell, "Error box"); - cell = row.getCell(5); - setCellValue(cell, "Other settings"); - } - - public ValidationAdder createValidationAdder(CellStyle cellStyle, int dataValidationType) { - return new ValidationAdder(_currentSheet, _style_1, _style_2, cellStyle, dataValidationType); - } - - void createDVDescriptionRow(String strTypeDescription) { - Sheet sheet = _currentSheet; - Row row = sheet.getRow(sheet.getPhysicalNumberOfRows()-1); - sheet.addMergedRegion(new CellRangeAddress(sheet.getPhysicalNumberOfRows()-1, sheet.getPhysicalNumberOfRows()-1, 0, 5)); - Cell cell = row.createCell(0); - setCellValue(cell, strTypeDescription); - cell.setCellStyle(_style_3); - row = sheet.createRow(sheet.getPhysicalNumberOfRows()); - } - } - - - private void addCustomValidations(WorkbookFormatter wf) { - wf.createSheet("Custom"); - wf.createHeaderRow(); - - ValidationAdder va = wf.createValidationAdder(null, ValidationType.FORMULA); - va.addValidation(OperatorType.BETWEEN, "ISNUMBER($A2)", null, ErrorStyle.STOP, "ISNUMBER(A2)", "Error box type = STOP", true, true, true); - va.addValidation(OperatorType.BETWEEN, "IF(SUM(A2:A3)=5,TRUE,FALSE)", null, ErrorStyle.WARNING, "IF(SUM(A2:A3)=5,TRUE,FALSE)", "Error box type = WARNING", false, false, true); - } - - private static void addSimpleNumericValidations(WorkbookFormatter wf) { - // data validation's number types - wf.createSheet("Numbers"); - - // "Whole number" validation type - wf.createDVTypeRow("Whole number"); - wf.createHeaderRow(); - - ValidationAdder va = wf.createValidationAdder(null, ValidationType.INTEGER); - va.addValidation(OperatorType.BETWEEN, "2", "6", ErrorStyle.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); - va.addValidation(OperatorType.NOT_BETWEEN, "2", "6", ErrorStyle.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); - va.addValidation(OperatorType.EQUAL, "=3+2", null, ErrorStyle.WARNING, "Equal to (3+2)", "Error box type = WARNING", false, false, true); - va.addValidation(OperatorType.NOT_EQUAL, "3", null, ErrorStyle.WARNING, "Not equal to 3", "-", false, false, false); - va.addValidation(OperatorType.GREATER_THAN, "3", null, ErrorStyle.WARNING, "Greater than 3", "-", true, false, false); - va.addValidation(OperatorType.LESS_THAN, "3", null, ErrorStyle.WARNING, "Less than 3", "-", true, true, false); - va.addValidation(OperatorType.GREATER_OR_EQUAL, "4", null, ErrorStyle.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); - va.addValidation(OperatorType.LESS_OR_EQUAL, "4", null, ErrorStyle.STOP, "Less than or equal to 4", "-", false, true, false); - - // "Decimal" validation type - wf.createDVTypeRow("Decimal"); - wf.createHeaderRow(); - - va = wf.createValidationAdder(null, ValidationType.DECIMAL); - va.addValidation(OperatorType.BETWEEN, "2", "6", ErrorStyle.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); - va.addValidation(OperatorType.NOT_BETWEEN, "2", "6", ErrorStyle.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); - va.addValidation(OperatorType.EQUAL, "3", null, ErrorStyle.WARNING, "Equal to 3", "Error box type = WARNING", false, false, true); - va.addValidation(OperatorType.NOT_EQUAL, "3", null, ErrorStyle.WARNING, "Not equal to 3", "-", false, false, false); - va.addValidation(OperatorType.GREATER_THAN, "=12/6", null, ErrorStyle.WARNING, "Greater than (12/6)", "-", true, false, false); - va.addValidation(OperatorType.LESS_THAN, "3", null, ErrorStyle.WARNING, "Less than 3", "-", true, true, false); - va.addValidation(OperatorType.GREATER_OR_EQUAL, "4", null, ErrorStyle.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); - va.addValidation(OperatorType.LESS_OR_EQUAL, "4", null, ErrorStyle.STOP, "Less than or equal to 4", "-", false, true, false); - } - - private static void addListValidations(WorkbookFormatter wf, Workbook wb) { - final String cellStrValue - = "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " - + "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " - + "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " - + "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 "; - final String dataSheetName = "list_data"; - // "List" Data Validation type - Sheet fSheet = wf.createSheet("Lists"); - Sheet dataSheet = wb.createSheet(dataSheetName); - - - wf.createDVTypeRow("Explicit lists - list items are explicitly provided"); - wf.createDVDescriptionRow("Disadvantage - sum of item's length should be less than 255 characters"); - wf.createHeaderRow(); - - ValidationAdder va = wf.createValidationAdder(null, ValidationType.LIST); - String listValsDescr = "POIFS,HSSF,HWPF,HPSF"; - String[] listVals = listValsDescr.split(","); - va.addListValidation(listVals, null, listValsDescr, false, false); - va.addListValidation(listVals, null, listValsDescr, false, true); - va.addListValidation(listVals, null, listValsDescr, true, false); - va.addListValidation(listVals, null, listValsDescr, true, true); - - - - wf.createDVTypeRow("Reference lists - list items are taken from others cells"); - wf.createDVDescriptionRow("Advantage - no restriction regarding the sum of item's length"); - wf.createHeaderRow(); - va = wf.createValidationAdder(null, ValidationType.LIST); - String strFormula = "$A$30:$A$39"; - va.addListValidation(null, strFormula, strFormula, false, false); - - strFormula = dataSheetName + "!$A$1:$A$10"; - va.addListValidation(null, strFormula, strFormula, false, false); - Name namedRange = wb.createName(); - namedRange.setNameName("myName"); - namedRange.setRefersToFormula(dataSheetName + "!$A$2:$A$7"); - strFormula = "myName"; - va.addListValidation(null, strFormula, strFormula, false, false); - strFormula = "offset(myName, 2, 1, 4, 2)"; // Note about last param '2': - // - Excel expects single row or single column when entered in UI, but process this OK otherwise - va.addListValidation(null, strFormula, strFormula, false, false); - - // add list data on same sheet - for (int i = 0; i < 10; i++) { - Row currRow = fSheet.createRow(i + 29); - setCellValue(currRow.createCell(0), cellStrValue); - } - // add list data on another sheet - for (int i = 0; i < 10; i++) { - Row currRow = dataSheet.createRow(i + 0); - setCellValue(currRow.createCell(0), "Data a" + i); - setCellValue(currRow.createCell(1), "Data b" + i); - setCellValue(currRow.createCell(2), "Data c" + i); - } - } - - private static void addDateTimeValidations(WorkbookFormatter wf, Workbook wb) { - wf.createSheet("Dates and Times"); - - DataFormat dataFormat = wb.createDataFormat(); - short fmtDate = dataFormat.getFormat("m/d/yyyy"); - short fmtTime = dataFormat.getFormat("h:mm"); - CellStyle cellStyle_date = wb.createCellStyle(); - cellStyle_date.setDataFormat(fmtDate); - CellStyle cellStyle_time = wb.createCellStyle(); - cellStyle_time.setDataFormat(fmtTime); - - wf.createDVTypeRow("Date ( cells are already formated as date - m/d/yyyy)"); - wf.createHeaderRow(); - - ValidationAdder va = wf.createValidationAdder(cellStyle_date, ValidationType.DATE); - va.addValidation(OperatorType.BETWEEN, "2004/01/02", "2004/01/06", ErrorStyle.STOP, "Between 1/2/2004 and 1/6/2004 ", "Error box type = STOP", true, true, true); - va.addValidation(OperatorType.NOT_BETWEEN, "2004/01/01", "2004/01/06", ErrorStyle.INFO, "Not between 1/2/2004 and 1/6/2004 ", "Error box type = INFO", false, true, true); - va.addValidation(OperatorType.EQUAL, "2004/03/02", null, ErrorStyle.WARNING, "Equal to 3/2/2004", "Error box type = WARNING", false, false, true); - va.addValidation(OperatorType.NOT_EQUAL, "2004/03/02", null, ErrorStyle.WARNING, "Not equal to 3/2/2004", "-", false, false, false); - va.addValidation(OperatorType.GREATER_THAN,"=DATEVALUE(\"4-Jul-2001\")", null, ErrorStyle.WARNING, "Greater than DATEVALUE('4-Jul-2001')", "-", true, false, false); - va.addValidation(OperatorType.LESS_THAN, "2004/03/02", null, ErrorStyle.WARNING, "Less than 3/2/2004", "-", true, true, false); - va.addValidation(OperatorType.GREATER_OR_EQUAL, "2004/03/02", null, ErrorStyle.STOP, "Greater than or equal to 3/2/2004", "Error box type = STOP", true, false, true); - va.addValidation(OperatorType.LESS_OR_EQUAL, "2004/03/04", null, ErrorStyle.STOP, "Less than or equal to 3/4/2004", "-", false, true, false); - - // "Time" validation type - wf.createDVTypeRow("Time ( cells are already formated as time - h:mm)"); - wf.createHeaderRow(); - - va = wf.createValidationAdder(cellStyle_time, ValidationType.TIME); - va.addValidation(OperatorType.BETWEEN, "12:00", "16:00", ErrorStyle.STOP, "Between 12:00 and 16:00 ", "Error box type = STOP", true, true, true); - va.addValidation(OperatorType.NOT_BETWEEN, "12:00", "16:00", ErrorStyle.INFO, "Not between 12:00 and 16:00 ", "Error box type = INFO", false, true, true); - va.addValidation(OperatorType.EQUAL, "13:35", null, ErrorStyle.WARNING, "Equal to 13:35", "Error box type = WARNING", false, false, true); - va.addValidation(OperatorType.NOT_EQUAL, "13:35", null, ErrorStyle.WARNING, "Not equal to 13:35", "-", false, false, false); - va.addValidation(OperatorType.GREATER_THAN,"12:00", null, ErrorStyle.WARNING, "Greater than 12:00", "-", true, false, false); - va.addValidation(OperatorType.LESS_THAN, "=1/2", null, ErrorStyle.WARNING, "Less than (1/2) -> 12:00", "-", true, true, false); - va.addValidation(OperatorType.GREATER_OR_EQUAL, "14:00", null, ErrorStyle.STOP, "Greater than or equal to 14:00", "Error box type = STOP", true, false, true); - va.addValidation(OperatorType.LESS_OR_EQUAL,"14:00", null, ErrorStyle.STOP, "Less than or equal to 14:00", "-", false, true, false); - } - - private static void addTextLengthValidations(WorkbookFormatter wf) { - wf.createSheet("Text lengths"); - wf.createHeaderRow(); - - ValidationAdder va = wf.createValidationAdder(null, ValidationType.TEXT_LENGTH); - va.addValidation(OperatorType.BETWEEN, "2", "6", ErrorStyle.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); - va.addValidation(OperatorType.NOT_BETWEEN, "2", "6", ErrorStyle.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); - va.addValidation(OperatorType.EQUAL, "3", null, ErrorStyle.WARNING, "Equal to 3", "Error box type = WARNING", false, false, true); - va.addValidation(OperatorType.NOT_EQUAL, "3", null, ErrorStyle.WARNING, "Not equal to 3", "-", false, false, false); - va.addValidation(OperatorType.GREATER_THAN, "3", null, ErrorStyle.WARNING, "Greater than 3", "-", true, false, false); - va.addValidation(OperatorType.LESS_THAN, "3", null, ErrorStyle.WARNING, "Less than 3", "-", true, true, false); - va.addValidation(OperatorType.GREATER_OR_EQUAL, "4", null, ErrorStyle.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); - va.addValidation(OperatorType.LESS_OR_EQUAL, "4", null, ErrorStyle.STOP, "Less than or equal to 4", "-", false, true, false); - } - - @Test - void testDataValidation() throws Exception { - log("\nTest no. 2 - Test Excel's Data validation mechanism"); - Workbook wb = _testDataProvider.createWorkbook(); - WorkbookFormatter wf = new WorkbookFormatter(wb); - - log(" Create sheet for Data Validation's number types ... "); - addSimpleNumericValidations(wf); - log("done !"); - - log(" Create sheet for 'List' Data Validation type ... "); - addListValidations(wf, wb); - log("done !"); - - log(" Create sheet for 'Date' and 'Time' Data Validation types ... "); - addDateTimeValidations(wf, wb); - log("done !"); - - log(" Create sheet for 'Text length' Data Validation type... "); - addTextLengthValidations(wf); - log("done !"); - - // Custom Validation type - log(" Create sheet for 'Custom' Data Validation type ... "); - addCustomValidations(wf); - log("done !"); - - _testDataProvider.writeOutAndReadBack(wb).close(); - - wb.close(); - } - - - - /* package */ static void setCellValue(Cell cell, String text) { - cell.setCellValue(text); - - } + private static void addListValidations(WorkbookFormatter wf, Workbook wb) { + final String cellStrValue + = "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " + + "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " + + "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " + + "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 "; + final String dataSheetName = "list_data"; + // "List" Data Validation type + Sheet fSheet = wf.createSheet("Lists"); + Sheet dataSheet = wb.createSheet(dataSheetName); + + + wf.createDVTypeRow("Explicit lists - list items are explicitly provided"); + wf.createDVDescriptionRow("Disadvantage - sum of item's length should be less than 255 characters"); + wf.createHeaderRow(); + + ValidationAdder va = wf.createValidationAdder(null, ValidationType.LIST); + String listValsDescr = "POIFS,HSSF,HWPF,HPSF"; + String[] listVals = listValsDescr.split(","); + va.addListValidation(listVals, null, listValsDescr, false, false); + va.addListValidation(listVals, null, listValsDescr, false, true); + va.addListValidation(listVals, null, listValsDescr, true, false); + va.addListValidation(listVals, null, listValsDescr, true, true); + + + wf.createDVTypeRow("Reference lists - list items are taken from others cells"); + wf.createDVDescriptionRow("Advantage - no restriction regarding the sum of item's length"); + wf.createHeaderRow(); + va = wf.createValidationAdder(null, ValidationType.LIST); + String strFormula = "$A$30:$A$39"; + va.addListValidation(null, strFormula, strFormula, false, false); + + strFormula = dataSheetName + "!$A$1:$A$10"; + va.addListValidation(null, strFormula, strFormula, false, false); + Name namedRange = wb.createName(); + namedRange.setNameName("myName"); + namedRange.setRefersToFormula(dataSheetName + "!$A$2:$A$7"); + strFormula = "myName"; + va.addListValidation(null, strFormula, strFormula, false, false); + strFormula = "offset(myName, 2, 1, 4, 2)"; // Note about last param '2': + // - Excel expects single row or single column when entered in UI, but process this OK otherwise + va.addListValidation(null, strFormula, strFormula, false, false); + + // add list data on same sheet + for (int i = 0; i < 10; i++) { + Row currRow = fSheet.createRow(i + 29); + setCellValue(currRow.createCell(0), cellStrValue); + } + // add list data on another sheet + for (int i = 0; i < 10; i++) { + Row currRow = dataSheet.createRow(i + 0); + setCellValue(currRow.createCell(0), "Data a" + i); + setCellValue(currRow.createCell(1), "Data b" + i); + setCellValue(currRow.createCell(2), "Data c" + i); + } + } + + private static void addDateTimeValidations(WorkbookFormatter wf, Workbook wb) { + wf.createSheet("Dates and Times"); + + DataFormat dataFormat = wb.createDataFormat(); + short fmtDate = dataFormat.getFormat("m/d/yyyy"); + short fmtTime = dataFormat.getFormat("h:mm"); + CellStyle cellStyle_date = wb.createCellStyle(); + cellStyle_date.setDataFormat(fmtDate); + CellStyle cellStyle_time = wb.createCellStyle(); + cellStyle_time.setDataFormat(fmtTime); + + wf.createDVTypeRow("Date ( cells are already formated as date - m/d/yyyy)"); + wf.createHeaderRow(); + + ValidationAdder va = wf.createValidationAdder(cellStyle_date, ValidationType.DATE); + va.addValidation(OperatorType.BETWEEN, "2004/01/02", "2004/01/06", ErrorStyle.STOP, "Between 1/2/2004 and 1/6/2004 ", "Error box type = STOP", true, true, true); + va.addValidation(OperatorType.NOT_BETWEEN, "2004/01/01", "2004/01/06", ErrorStyle.INFO, "Not between 1/2/2004 and 1/6/2004 ", "Error box type = INFO", false, true, true); + va.addValidation(OperatorType.EQUAL, "2004/03/02", null, ErrorStyle.WARNING, "Equal to 3/2/2004", "Error box type = WARNING", false, false, true); + va.addValidation(OperatorType.NOT_EQUAL, "2004/03/02", null, ErrorStyle.WARNING, "Not equal to 3/2/2004", "-", false, false, false); + va.addValidation(OperatorType.GREATER_THAN, "=DATEVALUE(\"4-Jul-2001\")", null, ErrorStyle.WARNING, "Greater than DATEVALUE('4-Jul-2001')", "-", true, false, false); + va.addValidation(OperatorType.LESS_THAN, "2004/03/02", null, ErrorStyle.WARNING, "Less than 3/2/2004", "-", true, true, false); + va.addValidation(OperatorType.GREATER_OR_EQUAL, "2004/03/02", null, ErrorStyle.STOP, "Greater than or equal to 3/2/2004", "Error box type = STOP", true, false, true); + va.addValidation(OperatorType.LESS_OR_EQUAL, "2004/03/04", null, ErrorStyle.STOP, "Less than or equal to 3/4/2004", "-", false, true, false); + + // "Time" validation type + wf.createDVTypeRow("Time ( cells are already formated as time - h:mm)"); + wf.createHeaderRow(); + + va = wf.createValidationAdder(cellStyle_time, ValidationType.TIME); + va.addValidation(OperatorType.BETWEEN, "12:00", "16:00", ErrorStyle.STOP, "Between 12:00 and 16:00 ", "Error box type = STOP", true, true, true); + va.addValidation(OperatorType.NOT_BETWEEN, "12:00", "16:00", ErrorStyle.INFO, "Not between 12:00 and 16:00 ", "Error box type = INFO", false, true, true); + va.addValidation(OperatorType.EQUAL, "13:35", null, ErrorStyle.WARNING, "Equal to 13:35", "Error box type = WARNING", false, false, true); + va.addValidation(OperatorType.NOT_EQUAL, "13:35", null, ErrorStyle.WARNING, "Not equal to 13:35", "-", false, false, false); + va.addValidation(OperatorType.GREATER_THAN, "12:00", null, ErrorStyle.WARNING, "Greater than 12:00", "-", true, false, false); + va.addValidation(OperatorType.LESS_THAN, "=1/2", null, ErrorStyle.WARNING, "Less than (1/2) -> 12:00", "-", true, true, false); + va.addValidation(OperatorType.GREATER_OR_EQUAL, "14:00", null, ErrorStyle.STOP, "Greater than or equal to 14:00", "Error box type = STOP", true, false, true); + va.addValidation(OperatorType.LESS_OR_EQUAL, "14:00", null, ErrorStyle.STOP, "Less than or equal to 14:00", "-", false, true, false); + } + + private static void addTextLengthValidations(WorkbookFormatter wf) { + wf.createSheet("Text lengths"); + wf.createHeaderRow(); + + ValidationAdder va = wf.createValidationAdder(null, ValidationType.TEXT_LENGTH); + va.addValidation(OperatorType.BETWEEN, "2", "6", ErrorStyle.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); + va.addValidation(OperatorType.NOT_BETWEEN, "2", "6", ErrorStyle.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); + va.addValidation(OperatorType.EQUAL, "3", null, ErrorStyle.WARNING, "Equal to 3", "Error box type = WARNING", false, false, true); + va.addValidation(OperatorType.NOT_EQUAL, "3", null, ErrorStyle.WARNING, "Not equal to 3", "-", false, false, false); + va.addValidation(OperatorType.GREATER_THAN, "3", null, ErrorStyle.WARNING, "Greater than 3", "-", true, false, false); + va.addValidation(OperatorType.LESS_THAN, "3", null, ErrorStyle.WARNING, "Less than 3", "-", true, true, false); + va.addValidation(OperatorType.GREATER_OR_EQUAL, "4", null, ErrorStyle.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); + va.addValidation(OperatorType.LESS_OR_EQUAL, "4", null, ErrorStyle.STOP, "Less than or equal to 4", "-", false, true, false); + } + + @Test + void testDataValidation() throws Exception { + try (Workbook wb1 = _testDataProvider.createWorkbook()) { + WorkbookFormatter wf1 = new WorkbookFormatter(wb1); + addSimpleNumericValidations(wf1); + addListValidations(wf1, wb1); + addDateTimeValidations(wf1, wb1); + addTextLengthValidations(wf1); + // Custom Validation type + addCustomValidations(wf1); + try (Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1)) { + Sheet sh = wb2.getSheet("Numbers"); + assertEquals(16, sh.getDataValidations().size()); + } + + } + } + + + static void setCellValue(Cell cell, String text) { + cell.setCellValue(text); + } }
\ No newline at end of file diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestNamedRange.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestNamedRange.java index 5715ab0cc9..60a676fc7b 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestNamedRange.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestNamedRange.java @@ -17,6 +17,7 @@ package org.apache.poi.ss.usermodel; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -25,21 +26,17 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.IOException; -import java.util.Arrays; import java.util.List; -import org.apache.poi.hssf.HSSFITestDataProvider; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.util.AreaReference; import org.apache.poi.ss.util.CellReference; -import org.apache.poi.util.IOUtils; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; /** * Tests of implementations of {@link org.apache.poi.ss.usermodel.Name}. - * - * @author Yegor Kozlov */ public abstract class BaseTestNamedRange { @@ -103,13 +100,13 @@ public abstract class BaseTestNamedRange { @Test public final void testUnicodeNamedRange() throws Exception { - try (HSSFWorkbook wb1 = new HSSFWorkbook()) { + try (Workbook wb1 = _testDataProvider.createWorkbook()) { wb1.createSheet("Test"); Name name = wb1.createName(); name.setNameName("\u03B1"); name.setRefersToFormula("Test!$D$3:$E$8"); - try (HSSFWorkbook wb2 = HSSFITestDataProvider.instance.writeOutAndReadBack(wb1)) { + try (Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1)) { Name name2 = wb2.getName("\u03B1"); assertNotNull(name2); @@ -637,71 +634,64 @@ public abstract class BaseTestNamedRange { // bug 56781: name validation only checks for first character's validity and presence of spaces // bug 60246: validate name does not allow DOT in named ranges - @Test - void testValid() throws IOException { - Workbook wb = _testDataProvider.createWorkbook(); - - Name name = wb.createName(); - for (String valid : Arrays.asList( - "Hello", - "number1", - "_underscore", - "underscore_", - "p.e.r.o.i.d.s", - "\\Backslash", - "Backslash\\" - )) { - name.setNameName(valid); + @ParameterizedTest + @ValueSource(strings = {"Hello", "number1", "_underscore", "underscore_", "p.e.r.o.i.d.s", "\\Backslash", "Backslash\\"}) + void testValid(String valid) throws IOException { + try (Workbook wb = _testDataProvider.createWorkbook()) { + Name name = wb.createName(); + assertDoesNotThrow(() -> name.setNameName(valid)); } - - wb.close(); } - @Test - void testInvalid() { + @ParameterizedTest + @ValueSource(strings = { + "1number", "Sheet1!A1", "Exclamation!", "Has Space", "Colon:", "A-Minus", "A+Plus", "Dollar$", ".periodAtBeginning", + //special shorthand + "R", "C", + // A1-style cell reference + "A1", + // R1C1-style cell reference + "R1C1", + "NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters..."+ + "NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters..."+ + "NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters..."+ + "NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters..."+ + "NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters" + }) + void testInvalid(String invalid) { Workbook wb = _testDataProvider.createWorkbook(); Name name = wb.createName(); - IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> name.setNameName("")); + IllegalArgumentException e; + e = assertThrows(IllegalArgumentException.class, () -> name.setNameName("")); assertEquals("Name cannot be blank", e.getMessage()); - for (String invalid : Arrays.asList( - "1number", - "Sheet1!A1", - "Exclamation!", - "Has Space", - "Colon:", - "A-Minus", - "A+Plus", - "Dollar$", - ".periodAtBeginning", - "R", //special shorthand - "C", //special shorthand - "A1", // A1-style cell reference - "R1C1", // R1C1-style cell reference - "NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters..."+ - "NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters..."+ - "NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters..."+ - "NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters..."+ - "NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters.NameThatIsLongerThan255Characters" - )) { - e = assertThrows(IllegalArgumentException.class, () -> name.setNameName(invalid)); - assertTrue(e.getMessage().startsWith("Invalid name: '"+invalid+"'")); - } - + e = assertThrows(IllegalArgumentException.class, () -> name.setNameName(invalid)); + assertTrue(e.getMessage().startsWith("Invalid name: '"+invalid+"'")); } // bug 60260: renaming a sheet with a named range referring to a unicode (non-ASCII) sheet name @Test - void renameSheetWithNamedRangeReferringToUnicodeSheetName() { - Workbook wb = _testDataProvider.createWorkbook(); - wb.createSheet("Sheet\u30FB1"); + void renameSheetWithNamedRangeReferringToUnicodeSheetName() throws IOException { + String unicodeName = "Sheet\u30FB201"; + String asciiName = "Sheet 1"; + String rangeName = "test_named_range"; + try (Workbook wb1 = _testDataProvider.createWorkbook()) { + wb1.createSheet(unicodeName); - Name name = wb.createName(); - name.setNameName("test_named_range"); - name.setRefersToFormula("'Sheet\u30FB201'!A1:A6"); + Name name1 = wb1.createName(); + name1.setNameName(rangeName); + name1.setRefersToFormula("'"+unicodeName+"'!A1:A6"); - wb.setSheetName(0, "Sheet 1"); - IOUtils.closeQuietly(wb); + wb1.setSheetName(0, asciiName); + assertEquals(asciiName, name1.getSheetName()); + + try (Workbook wb2 = _testDataProvider.writeOutAndReadBack(wb1)) { + Name name2 = wb2.getName(rangeName); + assertNotNull(name2); + // Eventually this will be updated, but currently we don't update the sheet name + assertEquals(asciiName, name2.getSheetName()); + } + } } } diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheet.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheet.java index 3a722b02ca..947bd71a9f 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheet.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheet.java @@ -18,6 +18,7 @@ package org.apache.poi.ss.usermodel; import static org.apache.poi.POITestCase.assertBetween; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -39,6 +40,7 @@ import java.util.Map.Entry; import java.util.Set; import org.apache.poi.common.usermodel.HyperlinkType; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.util.CellAddress; @@ -1039,7 +1041,7 @@ public abstract class BaseTestSheet { // here we can only verify that setting some zoom values works, // range-checking is different between the implementations - sheet.setZoom(75); + assertDoesNotThrow(() -> sheet.setZoom(75)); } } @@ -1048,6 +1050,10 @@ public abstract class BaseTestSheet { try (Workbook wb = _testDataProvider.createWorkbook()) { Sheet sheet = wb.createSheet(); sheet.showInPane(2, 3); + if (wb instanceof HSSFWorkbook) { + assertEquals(2, sheet.getTopRow()); + assertEquals(3, sheet.getLeftCol()); + } } } diff --git a/src/testcases/org/apache/poi/ss/util/TestDateFormatConverter.java b/src/testcases/org/apache/poi/ss/util/TestDateFormatConverter.java index 00697bbdb4..befe219a16 100644 --- a/src/testcases/org/apache/poi/ss/util/TestDateFormatConverter.java +++ b/src/testcases/org/apache/poi/ss/util/TestDateFormatConverter.java @@ -22,22 +22,24 @@ package org.apache.poi.ss.util; import static java.text.DateFormat.getDateInstance; import static java.text.DateFormat.getDateTimeInstance; import static java.text.DateFormat.getTimeInstance; +import static org.apache.poi.ss.util.DateFormatConverter.getPrefixForLocale; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.io.File; -import java.io.FileOutputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Comparator; import java.util.Date; import java.util.Locale; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; import org.apache.poi.hssf.usermodel.HSSFWorkbook; @@ -49,7 +51,6 @@ import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.util.LocaleID; import org.apache.poi.util.NullOutputStream; -import org.apache.poi.util.TempFile; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -74,50 +75,54 @@ final class TestDateFormatConverter { "false, true, " + DateFormat.FULL + ", Full" }) void testJavaDateFormatsInExcel(boolean dates, boolean times, int style, String styleName ) throws Exception { + String sheetName = (dates) ? ((times) ? "DateTimes" : "Dates") : "Times"; + String[] headers = { + "locale", "DisplayName", "Excel " + styleName, "java.text.DateFormat", + "Equals", "Java pattern", "Excel pattern" + }; + + Locale[] locales = Arrays.stream(DateFormat.getAvailableLocales()) + // only use locale with known LocaleIDs + .filter(l -> !getPrefixForLocale(l).isEmpty() || Locale.ROOT.equals(l) || l.toLanguageTag().isEmpty()) + .sorted(Comparator.comparing(Locale::toString)) + .toArray(Locale[]::new); + + try (Workbook workbook = new HSSFWorkbook()) { - String sheetName = (dates) ? ((times) ? "DateTimes" : "Dates") : "Times"; Sheet sheet = workbook.createSheet(sheetName); Row header = sheet.createRow(0); - header.createCell(0).setCellValue("locale"); - header.createCell(1).setCellValue("DisplayName"); - header.createCell(2).setCellValue("Excel " + styleName); - header.createCell(3).setCellValue("java.text.DateFormat"); - header.createCell(4).setCellValue("Equals"); - header.createCell(5).setCellValue("Java pattern"); - header.createCell(6).setCellValue("Excel pattern"); + IntStream.range(0, headers.length).forEach(i -> header.createCell(i).setCellValue(headers[i])); int rowNum = 1; - for (Locale locale : DateFormat.getAvailableLocales()) { - Row row = sheet.createRow(rowNum++); - - row.createCell(0).setCellValue(locale.toString()); - row.createCell(1).setCellValue(locale.getDisplayName(Locale.ROOT)); + final Cell[] cell = new Cell[7]; + final Date date = new Date(); + for (Locale locale : locales) { DateFormat dateFormat = (dates) ? (times ? getDateTimeInstance(style, style, locale) : getDateInstance(style, locale)) : getTimeInstance(style, locale); - - Cell cell = row.createCell(2); - Date date = new Date(); - cell.setCellValue(date); - CellStyle cellStyle = row.getSheet().getWorkbook().createCellStyle(); - String javaDateFormatPattern = ((SimpleDateFormat) dateFormat).toPattern(); String excelFormatPattern = DateFormatConverter.convert(locale, javaDateFormatPattern); - DataFormat poiFormat = row.getSheet().getWorkbook().createDataFormat(); + Row row = sheet.createRow(rowNum++); + IntStream.range(0, headers.length).forEach(i -> cell[i] = row.createCell(i)); + CellStyle cellStyle = workbook.createCellStyle(); + DataFormat poiFormat = workbook.createDataFormat(); cellStyle.setDataFormat(poiFormat.getFormat(excelFormatPattern)); - row.createCell(3).setCellValue(dateFormat.format(date)); - cell.setCellStyle(cellStyle); + cell[0].setCellValue(locale.toString()); + cell[1].setCellValue(locale.getDisplayName(Locale.ROOT)); + cell[2].setCellValue(date); + cell[2].setCellStyle(cellStyle); + cell[3].setCellValue(dateFormat.format(date)); // the formula returns TRUE is the formatted date in column C equals to the string in column D - row.createCell(4).setCellFormula("TEXT(C" + rowNum + ",G" + rowNum + ")=D" + rowNum); - row.createCell(5).setCellValue(javaDateFormatPattern); - row.createCell(6).setCellValue(excelFormatPattern); + cell[4].setCellFormula("TEXT(C" + rowNum + ",G" + rowNum + ")=D" + rowNum); + cell[5].setCellValue(javaDateFormatPattern); + cell[6].setCellValue(excelFormatPattern); } - workbook.write(new NullOutputStream()); + assertDoesNotThrow(() -> workbook.write(new NullOutputStream())); } } @@ -125,7 +130,7 @@ final class TestDateFormatConverter { void testJDK8EmptyLocale() { // JDK 8 seems to add an empty locale-string to the list returned via DateFormat.getAvailableLocales() // therefore we now cater for this special locale as well - String prefix = DateFormatConverter.getPrefixForLocale(new Locale("")); + String prefix = getPrefixForLocale(new Locale("")); assertEquals("", prefix); } @@ -163,7 +168,7 @@ final class TestDateFormatConverter { continue; } - String prefix = DateFormatConverter.getPrefixForLocale(loc); + String prefix = getPrefixForLocale(loc); assertNotNull(prefix, "Prefix not found - language tag: "+partTag); assertNotEquals("", prefix, "Prefix not found - language tag: "+partTag); Matcher m = p.matcher(prefix); |