git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1899082 13f79535-47bb-0310-9956-ffa450edef68tags/REL_5_2_3
@@ -135,11 +135,11 @@ public class TestAllFiles { | |||
final List<Arguments> result = new ArrayList<>(100); | |||
for (String file : scanner.getIncludedFiles()) { | |||
// avoid running on files leftover from previous failed runs | |||
// or being created by tests run in parallel | |||
if(file.endsWith("-saved.xls") || file.endsWith("TestHPSFWritingFunctionality.doc")) { | |||
continue; | |||
} | |||
// avoid running on files leftover from previous failed runs | |||
// or being created by tests run in parallel | |||
if(file.endsWith("-saved.xls") || file.endsWith("TestHPSFWritingFunctionality.doc")) { | |||
continue; | |||
} | |||
for (FileHandlerKnown handler : sm.getHandler(file)) { | |||
ExcInfo info1 = sm.getExcInfo(file, testName, handler); |
@@ -47,7 +47,7 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.CTUnsignedInt; | |||
*/ | |||
@Beta | |||
public abstract class XDDFChartData { | |||
private static final Logger LOGGER = LogManager.getLogger(XDDFChartData.class); | |||
private static final Logger LOGGER = LogManager.getLogger(XDDFChartData.class); | |||
protected XDDFChart parent; | |||
protected List<Series> series; |
@@ -244,20 +244,20 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing<XSS | |||
protected RelationPart createChartRelationPart() { | |||
XSSFWorkbook wb = getSheet().getWorkbook(); | |||
XSSFFactory factory = wb == null ? XSSFFactory.getInstance() : wb.getXssfFactory(); | |||
OPCPackage pkg = getPackagePart().getPackage(); | |||
int chartNumber = pkg.getPartsByContentType(XSSFRelation.CHART.getContentType()) | |||
OPCPackage pkg = getPackagePart().getPackage(); | |||
int chartNumber = pkg.getPartsByContentType(XSSFRelation.CHART.getContentType()) | |||
.size() + 1; | |||
// some broken files have incorrectly named package parts, | |||
// so we need to avoid duplicates here by checking and increasing | |||
// the part-number | |||
try { | |||
while (pkg.getPart(PackagingURIHelper.createPartName(XSSFRelation.CHART.getFileName(chartNumber))) != null) { | |||
chartNumber++; | |||
} | |||
} catch (InvalidFormatException e) { | |||
throw new IllegalStateException("Failed for " + chartNumber, e); | |||
} | |||
// some broken files have incorrectly named package parts, | |||
// so we need to avoid duplicates here by checking and increasing | |||
// the part-number | |||
try { | |||
while (pkg.getPart(PackagingURIHelper.createPartName(XSSFRelation.CHART.getFileName(chartNumber))) != null) { | |||
chartNumber++; | |||
} | |||
} catch (InvalidFormatException e) { | |||
throw new IllegalStateException("Failed for " + chartNumber, e); | |||
} | |||
return createRelationship(XSSFRelation.CHART, factory, chartNumber, false); | |||
} |
@@ -62,18 +62,18 @@ public final class XSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook { | |||
@Override | |||
public EvaluationSheet getSheet(int sheetIndex) { | |||
// verify index and let the method in _uBook throw the exception so we report | |||
// it the same way as in other places | |||
if (sheetIndex < 0 || sheetIndex >= _uBook.getNumberOfSheets()) { | |||
// this will throw an exception now as the index is out of bounds | |||
_uBook.getSheetAt(sheetIndex); | |||
} | |||
// verify index and let the method in _uBook throw the exception so we report | |||
// it the same way as in other places | |||
if (sheetIndex < 0 || sheetIndex >= _uBook.getNumberOfSheets()) { | |||
// this will throw an exception now as the index is out of bounds | |||
_uBook.getSheetAt(sheetIndex); | |||
} | |||
// Performance optimization: build sheet cache for each sheet to avoid re-creating | |||
// the XSSFEvaluationSheet each time a new cell is evaluated | |||
// the XSSFEvaluationSheet each time a new cell is evaluated | |||
// EvaluationWorkbooks make not guarantee to synchronize changes made to | |||
// the underlying workbook after the EvaluationWorkbook is created. | |||
final XSSFSheet sheet = _uBook.getSheetAt(sheetIndex); | |||
final XSSFSheet sheet = _uBook.getSheetAt(sheetIndex); | |||
return _sheetCache.computeIfAbsent(sheet, rows -> new XSSFEvaluationSheet(sheet)); | |||
} | |||
@@ -29,52 +29,52 @@ import org.junit.jupiter.api.Test; | |||
class TestXSSFEvaluationWorkbook { | |||
@Test | |||
void testRefToBlankCellInArrayFormula() { | |||
Workbook wb = new XSSFWorkbook(); | |||
FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); | |||
verifySheet(wb, formulaEvaluator); | |||
verifySheet(wb, formulaEvaluator); | |||
wb.getCreationHelper().createFormulaEvaluator().evaluateAll(); | |||
} | |||
private void verifySheet(Workbook wb, FormulaEvaluator formulaEvaluator) { | |||
Sheet sheet = wb.createSheet(); | |||
Row row = sheet.createRow(0); | |||
Cell cellA1 = row.createCell(0); | |||
Cell cellB1 = row.createCell(1); | |||
Cell cellC1 = row.createCell(2); | |||
Row row2 = sheet.createRow(1); | |||
Cell cellA2 = row2.createCell(0); | |||
Cell cellB2 = row2.createCell(1); | |||
Cell cellC2 = row2.createCell(2); | |||
Row row3 = sheet.createRow(2); | |||
Cell cellA3 = row3.createCell(0); | |||
Cell cellB3 = row3.createCell(1); | |||
Cell cellC3 = row3.createCell(2); | |||
cellA1.setCellValue("1"); | |||
// cell B1 intentionally left blank | |||
cellC1.setCellValue("3"); | |||
cellA2.setCellFormula("A1"); | |||
cellB2.setCellFormula("B1"); | |||
cellC2.setCellFormula("C1"); | |||
sheet.setArrayFormula("A1:C1", CellRangeAddress.valueOf("A3:C3")); | |||
formulaEvaluator.evaluateAll(); | |||
assertEquals("1", cellA2.getStringCellValue()); | |||
assertEquals(0,cellB2.getNumericCellValue(), 0.00001); | |||
assertEquals("3",cellC2.getStringCellValue()); | |||
assertEquals("1", cellA3.getStringCellValue()); | |||
assertEquals(0,cellB3.getNumericCellValue(), 0.00001); | |||
assertEquals("3",cellC3.getStringCellValue()); | |||
} | |||
@Test | |||
void testRefToBlankCellInArrayFormula() { | |||
Workbook wb = new XSSFWorkbook(); | |||
FormulaEvaluator formulaEvaluator = wb.getCreationHelper().createFormulaEvaluator(); | |||
verifySheet(wb, formulaEvaluator); | |||
verifySheet(wb, formulaEvaluator); | |||
wb.getCreationHelper().createFormulaEvaluator().evaluateAll(); | |||
} | |||
private void verifySheet(Workbook wb, FormulaEvaluator formulaEvaluator) { | |||
Sheet sheet = wb.createSheet(); | |||
Row row = sheet.createRow(0); | |||
Cell cellA1 = row.createCell(0); | |||
Cell cellB1 = row.createCell(1); | |||
Cell cellC1 = row.createCell(2); | |||
Row row2 = sheet.createRow(1); | |||
Cell cellA2 = row2.createCell(0); | |||
Cell cellB2 = row2.createCell(1); | |||
Cell cellC2 = row2.createCell(2); | |||
Row row3 = sheet.createRow(2); | |||
Cell cellA3 = row3.createCell(0); | |||
Cell cellB3 = row3.createCell(1); | |||
Cell cellC3 = row3.createCell(2); | |||
cellA1.setCellValue("1"); | |||
// cell B1 intentionally left blank | |||
cellC1.setCellValue("3"); | |||
cellA2.setCellFormula("A1"); | |||
cellB2.setCellFormula("B1"); | |||
cellC2.setCellFormula("C1"); | |||
sheet.setArrayFormula("A1:C1", CellRangeAddress.valueOf("A3:C3")); | |||
formulaEvaluator.evaluateAll(); | |||
assertEquals("1", cellA2.getStringCellValue()); | |||
assertEquals(0,cellB2.getNumericCellValue(), 0.00001); | |||
assertEquals("3",cellC2.getStringCellValue()); | |||
assertEquals("1", cellA3.getStringCellValue()); | |||
assertEquals(0,cellB3.getNumericCellValue(), 0.00001); | |||
assertEquals("3",cellC3.getStringCellValue()); | |||
} | |||
} |
@@ -129,9 +129,9 @@ public final class PPDrawing extends RecordAtom implements Iterable<EscherRecord | |||
// Build up a tree of Escher records contained within | |||
final DefaultEscherRecordFactory erf = new HSLFEscherRecordFactory(); | |||
dgContainer.fillFields(source, start + 8, erf); | |||
if (dgContainer.getRecordId() != EscherRecordTypes.DG_CONTAINER.typeID) { | |||
throw new IllegalArgumentException("Unexpected record type: " + dgContainer.getRecordId()); | |||
} | |||
if (dgContainer.getRecordId() != EscherRecordTypes.DG_CONTAINER.typeID) { | |||
throw new IllegalArgumentException("Unexpected record type: " + dgContainer.getRecordId()); | |||
} | |||
dg = dgContainer.getChildById(EscherRecordTypes.DG.typeID); | |||
textboxWrappers = Stream.of(dgContainer). |
@@ -199,22 +199,22 @@ public class SSSlideInfoAtom extends RecordAtom { | |||
ofs += _header.length; | |||
if (LittleEndian.getShort(_header, 0) != 0) { | |||
LOG.atDebug().log("Invalid data for SSSlideInfoAtom at offset 0: " + LittleEndian.getShort(_header, 0)); | |||
} | |||
if (LittleEndian.getShort(_header, 2) != RecordTypes.SSSlideInfoAtom.typeID) { | |||
LOG.atDebug().log("Invalid data for SSSlideInfoAtom at offset 2: "+ LittleEndian.getShort(_header, 2)); | |||
} | |||
if (LittleEndian.getShort(_header, 4) != 0x10) { | |||
LOG.atDebug().log("Invalid data for SSSlideInfoAtom at offset 4: "+ LittleEndian.getShort(_header, 4)); | |||
} | |||
if (LittleEndian.getShort(_header, 6) == 0) { | |||
LOG.atDebug().log("Invalid data for SSSlideInfoAtom at offset 6: "+ LittleEndian.getShort(_header, 6)); | |||
} | |||
LOG.atDebug().log("Invalid data for SSSlideInfoAtom at offset 0: " + LittleEndian.getShort(_header, 0)); | |||
} | |||
if (LittleEndian.getShort(_header, 2) != RecordTypes.SSSlideInfoAtom.typeID) { | |||
LOG.atDebug().log("Invalid data for SSSlideInfoAtom at offset 2: "+ LittleEndian.getShort(_header, 2)); | |||
} | |||
if (LittleEndian.getShort(_header, 4) != 0x10) { | |||
LOG.atDebug().log("Invalid data for SSSlideInfoAtom at offset 4: "+ LittleEndian.getShort(_header, 4)); | |||
} | |||
if (LittleEndian.getShort(_header, 6) == 0) { | |||
LOG.atDebug().log("Invalid data for SSSlideInfoAtom at offset 6: "+ LittleEndian.getShort(_header, 6)); | |||
} | |||
_slideTime = LittleEndian.getInt(source, ofs); | |||
if (_slideTime < 0 || _slideTime > 86399000) { | |||
LOG.atDebug().log("Invalid data for SSSlideInfoAtom - invalid slideTime: "+ _slideTime); | |||
} | |||
if (_slideTime < 0 || _slideTime > 86399000) { | |||
LOG.atDebug().log("Invalid data for SSSlideInfoAtom - invalid slideTime: "+ _slideTime); | |||
} | |||
ofs += LittleEndianConsts.INT_SIZE; | |||
_soundIdRef = LittleEndian.getInt(source, ofs); | |||
ofs += LittleEndianConsts.INT_SIZE; |
@@ -137,9 +137,9 @@ public final class UserEditAtom extends PositionDependentRecordAtom | |||
} | |||
if(offset-start != len) { | |||
throw new HSLFException("Having invalid data in UserEditAtom: " | |||
+ "len: " + len + ", offset: " + offset + ", start: " + start); | |||
} | |||
throw new HSLFException("Having invalid data in UserEditAtom: " | |||
+ "len: " + len + ", offset: " + offset + ", start: " + start); | |||
} | |||
} | |||
/** |
@@ -120,7 +120,7 @@ public class HSLFSlideShowEncrypted implements Closeable { | |||
recordMap.put(encOffset, r); | |||
} | |||
this.dea = (DocumentEncryptionAtom)r; | |||
this.dea = (DocumentEncryptionAtom)r; | |||
String pass = Biff8EncryptionKey.getCurrentUserPassword(); | |||
EncryptionInfo ei = getEncryptionInfo(); |
@@ -214,7 +214,7 @@ public final class HWPFDocument extends HWPFDocumentCore { | |||
* @param istream The InputStream that contains the Word document. | |||
* @throws IOException If there is an unexpected IOException from the passed | |||
* in InputStream. | |||
* @throws org.apache.poi.EmptyFileException If the given stream is empty | |||
* @throws org.apache.poi.EmptyFileException If the given stream is empty | |||
* @throws RuntimeException a number of other runtime exceptions can be thrown, especially if there are problems with the | |||
* input format | |||
*/ |
@@ -38,7 +38,7 @@ import static org.apache.logging.log4j.util.Unbox.box; | |||
*/ | |||
@Internal | |||
public final class OfficeArtContent { | |||
protected static final Logger LOG = LogManager.getLogger(OfficeArtContent.class); | |||
protected static final Logger LOG = LogManager.getLogger(OfficeArtContent.class); | |||
/** | |||
* {@link EscherRecordTypes#DGG_CONTAINER} containing drawing group information for the document. | |||
@@ -78,9 +78,9 @@ public final class OfficeArtContent { | |||
EscherRecordFactory recordFactory = new DefaultEscherRecordFactory(); | |||
int pos = offset; | |||
pos += drawingGroupData.fillFields(data, pos, recordFactory); | |||
if (drawingGroupData.getRecordId() == EscherRecordTypes.DGG_CONTAINER.typeID) { | |||
LOG.atDebug().log("Invalid record-id for filling Escher records: " + drawingGroupData.getRecordId()); | |||
} | |||
if (drawingGroupData.getRecordId() == EscherRecordTypes.DGG_CONTAINER.typeID) { | |||
LOG.atDebug().log("Invalid record-id for filling Escher records: " + drawingGroupData.getRecordId()); | |||
} | |||
/* | |||
* After the drawingGroupData there is an array (2 slots max) that has data about drawings. According to the | |||
@@ -98,16 +98,16 @@ public final class OfficeArtContent { | |||
byte dgglbl = data[pos]; | |||
if (dgglbl != 0x00 && dgglbl != 0x01) { | |||
throw new IllegalArgumentException("Invalid dgglbl when filling Escher records: " + dgglbl); | |||
} | |||
throw new IllegalArgumentException("Invalid dgglbl when filling Escher records: " + dgglbl); | |||
} | |||
pos++; | |||
EscherContainerRecord dgContainer = new EscherContainerRecord(); | |||
pos+= dgContainer.fillFields(data, pos, recordFactory); | |||
if (dgContainer.getRecordId() != EscherRecordTypes.DG_CONTAINER.typeID) { | |||
throw new IllegalArgumentException("Did have an invalid record-type: " + dgContainer.getRecordId() + | |||
" when filling Escher records"); | |||
} | |||
if (dgContainer.getRecordId() != EscherRecordTypes.DG_CONTAINER.typeID) { | |||
throw new IllegalArgumentException("Did have an invalid record-type: " + dgContainer.getRecordId() + | |||
" when filling Escher records"); | |||
} | |||
switch (dgglbl) { | |||
case 0x00: | |||
@@ -122,10 +122,10 @@ public final class OfficeArtContent { | |||
} | |||
} | |||
if (pos != offset + size) { | |||
throw new IllegalStateException("Did not read all data when filling Escher records: " | |||
+ "pos: " + pos + ", offset: " + offset + ", size: " + size); | |||
} | |||
if (pos != offset + size) { | |||
throw new IllegalStateException("Did not read all data when filling Escher records: " | |||
+ "pos: " + pos + ", offset: " + offset + ", size: " + size); | |||
} | |||
} | |||
private List<? extends EscherContainerRecord> getDgContainers() { |
@@ -72,6 +72,7 @@ public enum HyperlinkType { | |||
* | |||
* @return the old integer code for a HyperlinkType enum | |||
*/ | |||
@Deprecated | |||
@Internal(since="3.15 beta 3") | |||
int getCode() { | |||
return code; |
@@ -138,50 +138,50 @@ public final class ExtractorFactory { | |||
return (allPreferEventExtractors != null) ? allPreferEventExtractors : threadPreferEventExtractors.get(); | |||
} | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param fs The file-system which wraps the data of the file. | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
*/ | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param fs The file-system which wraps the data of the file. | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
*/ | |||
public static POITextExtractor createExtractor(POIFSFileSystem fs) throws IOException { | |||
return createExtractor(fs, getCurrentUserPassword()); | |||
} | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param fs The file-system which wraps the data of the file. | |||
* @param password The password that is necessary to open the file | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
*/ | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param fs The file-system which wraps the data of the file. | |||
* @param password The password that is necessary to open the file | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
*/ | |||
public static POITextExtractor createExtractor(POIFSFileSystem fs, String password) throws IOException { | |||
return createExtractor(fs.getRoot(), password); | |||
} | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param input A stream which wraps the data of the file. | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
* @throws EmptyFileException If the given file is empty | |||
*/ | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param input A stream which wraps the data of the file. | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
* @throws EmptyFileException If the given file is empty | |||
*/ | |||
public static POITextExtractor createExtractor(InputStream input) throws IOException { | |||
return createExtractor(input, getCurrentUserPassword()); | |||
} | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param input A stream which wraps the data of the file. | |||
* @param password The password that is necessary to open the file | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
* @throws EmptyFileException If the given file is empty | |||
*/ | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param input A stream which wraps the data of the file. | |||
* @param password The password that is necessary to open the file | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
* @throws EmptyFileException If the given file is empty | |||
*/ | |||
public static POITextExtractor createExtractor(InputStream input, String password) throws IOException { | |||
final InputStream is = FileMagic.prepareToCheckMagic(input); | |||
byte[] emptyFileCheck = new byte[1]; | |||
@@ -207,27 +207,27 @@ public final class ExtractorFactory { | |||
return wp(isOOXML ? FileMagic.OOXML : fm, w -> w.create(root, password)); | |||
} | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param file The file to read | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
* @throws EmptyFileException If the given file is empty | |||
*/ | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param file The file to read | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
* @throws EmptyFileException If the given file is empty | |||
*/ | |||
public static POITextExtractor createExtractor(File file) throws IOException { | |||
return createExtractor(file, getCurrentUserPassword()); | |||
} | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param file The file to read | |||
* @param password The password that is necessary to open the file | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
* @throws EmptyFileException If the given file is empty | |||
*/ | |||
/** | |||
* Create an extractor that can be used to read text from the given file. | |||
* | |||
* @param file The file to read | |||
* @param password The password that is necessary to open the file | |||
* @return A POITextExtractor that can be used to fetch text-content of the file. | |||
* @throws IOException If reading the file-data fails | |||
* @throws EmptyFileException If the given file is empty | |||
*/ | |||
@SuppressWarnings({"java:S2095"}) | |||
public static POITextExtractor createExtractor(File file, String password) throws IOException { | |||
if (file.length() == 0) { | |||
@@ -275,22 +275,22 @@ public final class ExtractorFactory { | |||
return createExtractor(root, getCurrentUserPassword()); | |||
} | |||
/** | |||
* Create the Extractor, if possible. Generally needs the Scratchpad jar. | |||
* Note that this won't check for embedded OOXML resources either, use | |||
* {@link org.apache.poi.ooxml.extractor.POIXMLExtractorFactory} for that. | |||
* | |||
* @param root The {@link DirectoryNode} pointing to a document. | |||
* @param password The password that is necessary to open the file | |||
* | |||
* @return The resulting {@link POITextExtractor}, an exception is thrown if | |||
* no TextExtractor can be created for some reason. | |||
* | |||
* @throws IOException If converting the {@link DirectoryNode} into a HSSFWorkbook fails | |||
* @throws org.apache.poi.OldFileFormatException If the {@link DirectoryNode} points to a format of | |||
* an unsupported version of Excel. | |||
* @throws IllegalArgumentException If creating the Extractor fails | |||
*/ | |||
/** | |||
* Create the Extractor, if possible. Generally needs the Scratchpad jar. | |||
* Note that this won't check for embedded OOXML resources either, use | |||
* {@link org.apache.poi.ooxml.extractor.POIXMLExtractorFactory} for that. | |||
* | |||
* @param root The {@link DirectoryNode} pointing to a document. | |||
* @param password The password that is necessary to open the file | |||
* | |||
* @return The resulting {@link POITextExtractor}, an exception is thrown if | |||
* no TextExtractor can be created for some reason. | |||
* | |||
* @throws IOException If converting the {@link DirectoryNode} into a HSSFWorkbook fails | |||
* @throws org.apache.poi.OldFileFormatException If the {@link DirectoryNode} points to a format of | |||
* an unsupported version of Excel. | |||
* @throws IllegalArgumentException If creating the Extractor fails | |||
*/ | |||
public static POITextExtractor createExtractor(final DirectoryNode root, String password) throws IOException { | |||
// Encrypted OOXML files go inside OLE2 containers, is this one? | |||
if (root.hasEntry(DEFAULT_POIFS_ENTRY) || root.hasEntry(OOXML_PACKAGE)) { | |||
@@ -300,22 +300,22 @@ public final class ExtractorFactory { | |||
} | |||
} | |||
/** | |||
* Returns an array of text extractors, one for each of | |||
* the embedded documents in the file (if there are any). | |||
* If there are no embedded documents, you'll get back an | |||
* empty array. Otherwise, you'll get one open | |||
* {@link POITextExtractor} for each embedded file. | |||
* | |||
* @param ext The extractor to look at for embedded documents | |||
* | |||
* @return An array of resulting extractors. Empty if no embedded documents are found. | |||
* | |||
* @throws IOException If converting the {@link DirectoryNode} into a HSSFWorkbook fails | |||
* @throws org.apache.poi.OldFileFormatException If the {@link DirectoryNode} points to a format of | |||
* an unsupported version of Excel. | |||
* @throws IllegalArgumentException If creating the Extractor fails | |||
*/ | |||
/** | |||
* Returns an array of text extractors, one for each of | |||
* the embedded documents in the file (if there are any). | |||
* If there are no embedded documents, you'll get back an | |||
* empty array. Otherwise, you'll get one open | |||
* {@link POITextExtractor} for each embedded file. | |||
* | |||
* @param ext The extractor to look at for embedded documents | |||
* | |||
* @return An array of resulting extractors. Empty if no embedded documents are found. | |||
* | |||
* @throws IOException If converting the {@link DirectoryNode} into a HSSFWorkbook fails | |||
* @throws org.apache.poi.OldFileFormatException If the {@link DirectoryNode} points to a format of | |||
* an unsupported version of Excel. | |||
* @throws IllegalArgumentException If creating the Extractor fails | |||
*/ | |||
public static POITextExtractor[] getEmbeddedDocsTextExtractors(POIOLE2TextExtractor ext) throws IOException { | |||
if (ext == null) { | |||
throw new IllegalStateException("extractor must be given"); |
@@ -420,9 +420,9 @@ public final class RecordInputStream implements LittleEndianInput { | |||
nextRecord(); | |||
// note - the compressed flag may change on the fly | |||
byte compressFlag = readByte(); | |||
if (compressFlag != 0 && compressFlag != 1) { | |||
throw new RecordFormatException("Invalid compressFlag: " + compressFlag); | |||
} | |||
if (compressFlag != 0 && compressFlag != 1) { | |||
throw new RecordFormatException("Invalid compressFlag: " + compressFlag); | |||
} | |||
isCompressedEncoding = (compressFlag == 0); | |||
} | |||
} |
@@ -1490,6 +1490,7 @@ public final class HSSFSheet implements Sheet { | |||
* @param isRow unused, kept for backwards compatibility | |||
* @deprecated POI 3.15 beta 2. Use {@link HSSFRowShifter#shiftMergedRegions(int, int, int)}. | |||
*/ | |||
@Deprecated | |||
protected void shiftMerged(int startRow, int endRow, int n, boolean isRow) { | |||
RowShifter rowShifter = new HSSFRowShifter(this); | |||
rowShifter.shiftMergedRegions(startRow, endRow, n); |
@@ -935,22 +935,22 @@ public final class HSSFWorkbook extends POIDocument implements Workbook { | |||
throw new IllegalArgumentException("sheetName must not be null"); | |||
} | |||
if (workbook.doesContainsSheetName(sheetname, _sheets.size())) { | |||
throw new IllegalArgumentException("The workbook already contains a sheet named '" + sheetname + "'"); | |||
} | |||
if (workbook.doesContainsSheetName(sheetname, _sheets.size())) { | |||
throw new IllegalArgumentException("The workbook already contains a sheet named '" + sheetname + "'"); | |||
} | |||
// YK: Mimic Excel and silently truncate sheet names longer than 31 characters | |||
// YK: Mimic Excel and silently truncate sheet names longer than 31 characters | |||
// Issue a WARNING though in order to prevent a situation, where the provided long sheet name is | |||
// not accessible due to the trimming while we are not even aware of the reason and continue to use | |||
// the long name in generated formulas | |||
if(sheetname.length() > MAX_SENSITIVE_SHEET_NAME_LEN) { | |||
String trimmedSheetname = sheetname.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN); | |||
// we still need to warn about the trimming as the original sheet name won't be available | |||
// e.g. when referenced by formulas | |||
LOGGER.atWarn().log("Sheet '{}' will be added with a trimmed name '{}' for MS Excel compliance.", | |||
sheetname, trimmedSheetname); | |||
sheetname = trimmedSheetname; | |||
// we still need to warn about the trimming as the original sheet name won't be available | |||
// e.g. when referenced by formulas | |||
LOGGER.atWarn().log("Sheet '{}' will be added with a trimmed name '{}' for MS Excel compliance.", | |||
sheetname, trimmedSheetname); | |||
sheetname = trimmedSheetname; | |||
} | |||
HSSFSheet sheet = new HSSFSheet(this); |
@@ -94,7 +94,7 @@ import org.apache.poi.util.LocaleUtil; | |||
*/ | |||
public class CellFormat { | |||
/** The logger to use in the formatting code. */ | |||
private static final Logger LOG = LogManager.getLogger(CellFormat.class); | |||
private static final Logger LOG = LogManager.getLogger(CellFormat.class); | |||
private static final Pattern ONE_PART = Pattern.compile( | |||
CellFormatPart.FORMAT_PAT.pattern() + "(;|$)", |
@@ -30,13 +30,13 @@ import org.apache.poi.util.Internal; | |||
@Internal | |||
public interface EvaluationWorkbook { | |||
/** | |||
* Returns the name of the sheet at the given 0-based index. | |||
* | |||
* @param sheetIndex The 0-based index of the sheet | |||
* @return The name of the sheet | |||
* @throws IllegalArgumentException If the index is outside the indices of available sheets | |||
*/ | |||
/** | |||
* Returns the name of the sheet at the given 0-based index. | |||
* | |||
* @param sheetIndex The 0-based index of the sheet | |||
* @return The name of the sheet | |||
* @throws IllegalArgumentException If the index is outside the indices of available sheets | |||
*/ | |||
String getSheetName(int sheetIndex); | |||
/** | |||
@@ -50,28 +50,28 @@ public interface EvaluationWorkbook { | |||
*/ | |||
int getSheetIndex(String sheetName); | |||
/** | |||
* Get the sheet identified by the given 0-based index. | |||
* | |||
* @param sheetIndex The 0-based index of the sheet | |||
* @return The sheet | |||
* @throws IllegalArgumentException If the index is outside the indices of available sheets | |||
*/ | |||
/** | |||
* Get the sheet identified by the given 0-based index. | |||
* | |||
* @param sheetIndex The 0-based index of the sheet | |||
* @return The sheet | |||
* @throws IllegalArgumentException If the index is outside the indices of available sheets | |||
*/ | |||
EvaluationSheet getSheet(int sheetIndex); | |||
/** | |||
* HSSF Only - fetch the external-style sheet details | |||
* <p>Return will have no workbook set if it's actually in our own workbook</p> | |||
* @return The found sheet or null if not found | |||
* @throws IllegalStateException If called with XSSF or SXSSF workbooks | |||
* @return The found sheet or null if not found | |||
* @throws IllegalStateException If called with XSSF or SXSSF workbooks | |||
*/ | |||
ExternalSheet getExternalSheet(int externSheetIndex); | |||
/** | |||
* XSSF Only - fetch the external-style sheet details | |||
* <p>Return will have no workbook set if it's actually in our own workbook</p> | |||
* @return The found sheet | |||
* @throws IllegalStateException If called with HSSF workbooks | |||
* @return The found sheet | |||
* @throws IllegalStateException If called with HSSF workbooks | |||
*/ | |||
ExternalSheet getExternalSheet(String firstSheetName, String lastSheetName, int externalWorkbookNumber); | |||
/** |
@@ -74,25 +74,25 @@ final class SheetRangeEvaluator implements SheetRange { | |||
return getSheetEvaluator(sheetIndex).getEvalForCell(rowIndex, columnIndex); | |||
} | |||
/** | |||
* This method returns a lower row-number if it would lie outside the row-boundaries of | |||
* any sheet. | |||
* | |||
* This is used to optimize cases where very high number of rows would be checked otherwise | |||
* without any benefit as no such row exists anyway. | |||
* | |||
* @param rowIndex The 0-based row-index to check | |||
* @return If the given index lies withing the max row number across all sheets, it is returned. | |||
* Otherwise, the highest used row number across all sheets is returned. | |||
*/ | |||
public int adjustRowNumber(int rowIndex) { | |||
int maxRowNum = rowIndex; | |||
/** | |||
* This method returns a lower row-number if it would lie outside the row-boundaries of | |||
* any sheet. | |||
* | |||
* This is used to optimize cases where very high number of rows would be checked otherwise | |||
* without any benefit as no such row exists anyway. | |||
* | |||
* @param rowIndex The 0-based row-index to check | |||
* @return If the given index lies withing the max row number across all sheets, it is returned. | |||
* Otherwise, the highest used row number across all sheets is returned. | |||
*/ | |||
public int adjustRowNumber(int rowIndex) { | |||
int maxRowNum = rowIndex; | |||
for (int i = _firstSheetIndex; i < _lastSheetIndex; i++) { | |||
maxRowNum = Math.max(maxRowNum, _sheetEvaluators[i].getLastRowNum()); | |||
} | |||
for (int i = _firstSheetIndex; i < _lastSheetIndex; i++) { | |||
maxRowNum = Math.max(maxRowNum, _sheetEvaluators[i].getLastRowNum()); | |||
} | |||
// do not try to evaluate further than there are rows in any sheet | |||
return Math.min(rowIndex, maxRowNum); | |||
} | |||
// do not try to evaluate further than there are rows in any sheet | |||
return Math.min(rowIndex, maxRowNum); | |||
} | |||
} |
@@ -90,10 +90,10 @@ final class SheetRefEvaluator { | |||
return getSheet().isRowHidden(rowIndex); | |||
} | |||
/** | |||
* @return The last used row in this sheet | |||
*/ | |||
public int getLastRowNum() { | |||
return getSheet().getLastRowNum(); | |||
} | |||
/** | |||
* @return The last used row in this sheet | |||
*/ | |||
public int getLastRowNum() { | |||
return getSheet().getLastRowNum(); | |||
} | |||
} |
@@ -66,20 +66,18 @@ public enum CellType { | |||
* @since POI 3.15 beta 3 | |||
* @deprecated POI 3.15 beta 3 | |||
*/ | |||
@Deprecated | |||
private final int code; | |||
/** | |||
* @since POI 3.15 beta 3 | |||
* @deprecated POI 3.15 beta 3 | |||
*/ | |||
private CellType(int code) { | |||
this.code = code; | |||
} | |||
/** | |||
* @since POI 3.15 beta 3. | |||
* @deprecated POI 3.15 beta 3. Used to transition code from <code>int</code>s to <code>CellType</code>s. | |||
*/ | |||
@Deprecated | |||
public static CellType forInt(int code) { | |||
for (CellType type : values()) { | |||
if (type.code == code) { | |||
@@ -93,6 +91,7 @@ public enum CellType { | |||
* @since POI 3.15 beta 3 | |||
* @deprecated POI 3.15 beta 3 | |||
*/ | |||
@Deprecated | |||
public int getCode() { | |||
return code; | |||
} |
@@ -177,7 +177,7 @@ public final class WorkbookFactory { | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the Workbook given is password protected | |||
* @throws EmptyFileException If the given data is empty | |||
* @throws EmptyFileException If the given data is empty | |||
* @throws RuntimeException a number of other runtime exceptions can be thrown, especially if there are problems with the | |||
* input format | |||
*/ | |||
@@ -206,7 +206,7 @@ public final class WorkbookFactory { | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the wrong password is given for a protected file | |||
* @throws EmptyFileException If the given data is empty | |||
* @throws EmptyFileException If the given data is empty | |||
* @throws RuntimeException a number of other runtime exceptions can be thrown, especially if there are problems with the | |||
* input format | |||
*/ | |||
@@ -247,7 +247,7 @@ public final class WorkbookFactory { | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the Workbook given is password protected | |||
* @throws EmptyFileException If the given data is empty | |||
* @throws EmptyFileException If the given data is empty | |||
* @throws RuntimeException a number of other runtime exceptions can be thrown, especially if there are problems with the | |||
* input format | |||
*/ | |||
@@ -269,7 +269,7 @@ public final class WorkbookFactory { | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the wrong password is given for a protected file | |||
* @throws EmptyFileException If the given data is empty | |||
* @throws EmptyFileException If the given data is empty | |||
* @throws RuntimeException a number of other runtime exceptions can be thrown, especially if there are problems with the | |||
* input format | |||
*/ | |||
@@ -293,7 +293,7 @@ public final class WorkbookFactory { | |||
* | |||
* @throws IOException if an error occurs while reading the data | |||
* @throws EncryptedDocumentException If the wrong password is given for a protected file | |||
* @throws EmptyFileException If the given data is empty | |||
* @throws EmptyFileException If the given data is empty | |||
* @throws RuntimeException a number of other runtime exceptions can be thrown, especially if there are problems with the | |||
* input format | |||
*/ |
@@ -916,16 +916,16 @@ public abstract class BaseTestWorkbook { | |||
} | |||
} | |||
@Test | |||
void testSheetNameTrimming() throws IOException { | |||
try (Workbook workbook = _testDataProvider.createWorkbook()) { | |||
Sheet sheet = workbook.createSheet("MyVeryLongSheetName_9999999999999999"); | |||
assertNotNull(sheet); | |||
assertEquals("MyVeryLongSheetName_99999999999", workbook.getSheetName(0)); | |||
assertThrows(IllegalArgumentException.class, | |||
() -> workbook.createSheet("MyVeryLongSheetName_9999999999999998") | |||
); | |||
} | |||
} | |||
@Test | |||
void testSheetNameTrimming() throws IOException { | |||
try (Workbook workbook = _testDataProvider.createWorkbook()) { | |||
Sheet sheet = workbook.createSheet("MyVeryLongSheetName_9999999999999999"); | |||
assertNotNull(sheet); | |||
assertEquals("MyVeryLongSheetName_99999999999", workbook.getSheetName(0)); | |||
assertThrows(IllegalArgumentException.class, | |||
() -> workbook.createSheet("MyVeryLongSheetName_9999999999999998") | |||
); | |||
} | |||
} | |||
} |