You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tika.apache.org by ta...@apache.org on 2018/07/27 14:16:57 UTC

[tika] 23/30: TIKA-2479 Output missing left/mid cells in XLSX and XLSB, and optionally also missing rows

This is an automated email from the ASF dual-hosted git repository.

tallison pushed a commit to branch branch_1x
in repository https://gitbox.apache.org/repos/asf/tika.git

commit dcfbe5a2d578696dfba309dec400e977f047cfb2
Author: Nick Burch <ni...@gagravarr.org>
AuthorDate: Thu May 17 23:07:04 2018 +0100

    TIKA-2479 Output missing left/mid cells in XLSX and XLSB, and optionally also missing rows
---
 .../ooxml/XSSFBExcelExtractorDecorator.java        |  2 +-
 .../ooxml/XSSFExcelExtractorDecorator.java         | 35 ++++++++++++++++++----
 .../org/apache/tika/parser/TabularFormatsTest.java | 11 ++++++-
 3 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFBExcelExtractorDecorator.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFBExcelExtractorDecorator.java
index 0a511c2..0367afc 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFBExcelExtractorDecorator.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFBExcelExtractorDecorator.java
@@ -118,7 +118,7 @@ public class XSSFBExcelExtractorDecorator extends XSSFExcelExtractorDecorator {
             addDrawingHyperLinks(sheetPart);
             sheetParts.add(sheetPart);
 
-            SheetTextAsHTML sheetExtractor = new SheetTextAsHTML(config.getIncludeHeadersAndFooters(), xhtml);
+            SheetTextAsHTML sheetExtractor = new SheetTextAsHTML(config, xhtml);
             XSSFBCommentsTable comments = iter.getXSSFBSheetComments();
 
             // Start, and output the sheet name
diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFExcelExtractorDecorator.java b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFExcelExtractorDecorator.java
index bf6505b..3141148 100644
--- a/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFExcelExtractorDecorator.java
+++ b/tika-parsers/src/main/java/org/apache/tika/parser/microsoft/ooxml/XSSFExcelExtractorDecorator.java
@@ -25,7 +25,6 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
-import org.apache.poi.POIXMLDocument;
 import org.apache.poi.POIXMLTextExtractor;
 import org.apache.poi.hssf.extractor.ExcelExtractor;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
@@ -39,6 +38,7 @@ import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.TargetMode;
 import org.apache.poi.ss.usermodel.DataFormatter;
 import org.apache.poi.ss.usermodel.HeaderFooter;
+import org.apache.poi.ss.util.CellReference;
 import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
 import org.apache.poi.xssf.eventusermodel.XSSFReader;
 import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
@@ -57,6 +57,7 @@ import org.apache.tika.metadata.Metadata;
 import org.apache.tika.metadata.TikaCoreProperties;
 import org.apache.tika.metadata.TikaMetadataKeys;
 import org.apache.tika.parser.ParseContext;
+import org.apache.tika.parser.microsoft.OfficeParserConfig;
 import org.apache.tika.parser.microsoft.TikaExcelDataFormatter;
 import org.apache.tika.sax.OfflineContentHandler;
 import org.apache.tika.sax.XHTMLContentHandler;
@@ -146,8 +147,7 @@ public class XSSFExcelExtractorDecorator extends AbstractOOXMLExtractor {
         }
 
         while (iter.hasNext()) {
-
-            SheetTextAsHTML sheetExtractor = new SheetTextAsHTML(config.getIncludeHeadersAndFooters(), xhtml);
+            SheetTextAsHTML sheetExtractor = new SheetTextAsHTML(config, xhtml);
             PackagePart sheetPart = null;
             try (InputStream stream = iter.next()) {
                 sheetPart = iter.getSheetPart();
@@ -396,11 +396,15 @@ public class XSSFExcelExtractorDecorator extends AbstractOOXMLExtractor {
     protected static class SheetTextAsHTML implements SheetContentsHandler {
         private XHTMLContentHandler xhtml;
         private final boolean includeHeadersFooters;
+        private final boolean includeMissingRows;
         protected List<String> headers;
         protected List<String> footers;
+        private int lastSeenRow = -1;
+        private int lastSeenCol = -1;
 
-        protected SheetTextAsHTML(boolean includeHeaderFooters, XHTMLContentHandler xhtml) {
-            this.includeHeadersFooters = includeHeaderFooters;
+        protected SheetTextAsHTML(OfficeParserConfig config, XHTMLContentHandler xhtml) {
+            this.includeHeadersFooters = config.getIncludeHeadersAndFooters();
+            this.includeMissingRows = config.getIncludeMissingRows();
             this.xhtml = xhtml;
             headers = new ArrayList<String>();
             footers = new ArrayList<String>();
@@ -408,7 +412,19 @@ public class XSSFExcelExtractorDecorator extends AbstractOOXMLExtractor {
 
         public void startRow(int rowNum) {
             try {
+                // Missing rows, if desired, with a single empty row
+                if (includeMissingRows && rowNum > (lastSeenRow+1)) {
+                    for (int rn=lastSeenRow+1; rn<rowNum; rn++) {
+                        xhtml.startElement("tr");
+                        xhtml.startElement("td");
+                        xhtml.endElement("td");
+                        xhtml.endElement("tr");
+                    }
+                }
+
+                // Start the new row
                 xhtml.startElement("tr");
+                lastSeenCol = -1;
             } catch (SAXException e) {
             }
         }
@@ -422,6 +438,15 @@ public class XSSFExcelExtractorDecorator extends AbstractOOXMLExtractor {
 
         public void cell(String cellRef, String formattedValue, XSSFComment comment) {
             try {
+                // Handle any missing cells
+                int colNum = (new CellReference(cellRef)).getCol();
+                for (int cn=lastSeenCol+1; cn<colNum; cn++) {
+                    xhtml.startElement("td");
+                    xhtml.endElement("td");
+                }
+                lastSeenCol = colNum;
+
+                // Start this cell
                 xhtml.startElement("td");
 
                 // Main cell contents
diff --git a/tika-parsers/src/test/java/org/apache/tika/parser/TabularFormatsTest.java b/tika-parsers/src/test/java/org/apache/tika/parser/TabularFormatsTest.java
index ea326bd..41139e2 100644
--- a/tika-parsers/src/test/java/org/apache/tika/parser/TabularFormatsTest.java
+++ b/tika-parsers/src/test/java/org/apache/tika/parser/TabularFormatsTest.java
@@ -234,9 +234,18 @@ public class TabularFormatsTest extends TikaTest {
         XMLResult result = getXML("test-columnar.xlsx");
         String xml = result.xml;
         assertHeaders(xml, false, true, false);
-        // TODO Correctly handle empty cells then enable this test
+        // TODO Fix formatting in export then enable this test
         //assertContents(xml, true, false);
     }
+    // Get a test XLSB file, then enable this unit test
+//    @Test
+//    public void testXLSB() throws Exception {
+//        XMLResult result = getXML("test-columnar.xlsb");
+//        String xml = result.xml;
+//        assertHeaders(xml, false, true, false);
+//        assertContents(xml, true, false);
+//    }
+
     // TODO Fix the ODS test - currently failing with
     // org.xml.sax.SAXException: Namespace http://www.w3.org/1999/xhtml not declared
 //    @Test