【问题标题】:How to list all embedded files from a microsoft office document, using Apache POI?如何使用 Apache POI 列出 Microsoft Office 文档中的所有嵌入文件?
【发布时间】:2016-03-21 13:03:06
【问题描述】:

是否有机会列出办公室文件(doc、docx、xls、xlsx、ppt、pptx、...)中的所有嵌入对象(doc、...、txt)?

我正在使用 Apache POI (Java) 库从办公文件中提取文本。我不需要从嵌入对象中提取所有文本,包含所有嵌入文档的文件名的日志文件会很好(例如:string objectFileNames = getEmbeddedFileNames(fileInputStream))。

示例:我有一个 Word 文档“test.doc”,其中包含另一个名为“excel.xls”的文件。我想将 excel.xls 的文件名(在这种情况下)写入日志文件。

我使用 apache 主页 (https://poi.apache.org/text-extraction.html) 中的一些示例代码进行了尝试。但我的代码总是返回相同的(“页脚文本:页眉文本”)。

我尝试的是:

private static void test(String inputfile, String outputfile) throws Exception {

    String[] extractedText = new String[100];
    int emb = 0;//used for counter of embedded objects

    InputStream fis = new FileInputStream(inputfile);
    PrintWriter out = new PrintWriter(outputfile);//Text in File (txt) schreiben

System.out.println("Emmbedded Search started. Inputfile: " + inputfile);

//Based on Apache sample Code
emb = 0;//Reset Counter

POIFSFileSystem emb_fileSystem = new POIFSFileSystem(fis);
// Firstly, get an extractor for the Workbook
POIOLE2TextExtractor oleTextExtractor = 
   ExtractorFactory.createExtractor(emb_fileSystem);
// Then a List of extractors for any embedded Excel, Word, PowerPoint
// or Visio objects embedded into it.
POITextExtractor[] embeddedExtractors =
   ExtractorFactory.getEmbededDocsTextExtractors(oleTextExtractor);

for (POITextExtractor textExtractor : embeddedExtractors) {
   // If the embedded object was an Excel spreadsheet.
   if (textExtractor instanceof ExcelExtractor) {
      ExcelExtractor excelExtractor = (ExcelExtractor) textExtractor;
      extractedText[emb] = (excelExtractor.getText());
   }
   // A Word Document
   else if (textExtractor instanceof WordExtractor) {
      WordExtractor wordExtractor = (WordExtractor) textExtractor;
      String[] paragraphText = wordExtractor.getParagraphText();
      for (String paragraph : paragraphText) {
          extractedText[emb] = paragraph;
      }
      // Display the document's header and footer text
      System.out.println("Footer text: " + wordExtractor.getFooterText());
      System.out.println("Header text: " + wordExtractor.getHeaderText());
   }
   // PowerPoint Presentation.
   else if (textExtractor instanceof PowerPointExtractor) {
      PowerPointExtractor powerPointExtractor =
         (PowerPointExtractor) textExtractor;
      extractedText[emb] = powerPointExtractor.getText();
      emb++;
      extractedText[emb] =  powerPointExtractor.getNotes();
   }
   // Visio Drawing
   else if (textExtractor instanceof VisioTextExtractor) {
      VisioTextExtractor visioTextExtractor = 
         (VisioTextExtractor) textExtractor;
      extractedText[emb] = visioTextExtractor.getText();
   }
   emb++;//Count Embedded Objects
}//Close For Each Loop POIText...

for(int x = 0; x <= extractedText.length; x++){//Write Results to TXT
    if (extractedText[x] != null){
        System.out.println(extractedText[x]);
        out.println(extractedText[x]);
    }
    else {
        break;
    }
}
out.close();

}

Inputfile 是 xls,它包含一个 doc 文件作为 object,而 outputfile 是 txt。

如果有人可以帮助我,谢谢。

【问题讨论】:

    标签: java apache-poi text-extraction embedded-object


    【解决方案1】:

    我认为嵌入式 OLE 对象不会保留其原始文件名,所以我认为您想要的不是真的。

    我相信Microsoft writes about embedded images 也适用于 OLE 对象:

    您可能会注意到图像文件的文件名已从 Eagle1.gif 更改为 image1.gif。这样做是为了解决隐私问题,因为恶意的人可以从文档中的部分名称(例如图像文件)中获得竞争优势。例如,作者可能选择通过加密文档文件的文本部分来保护文档的内容。但是,如果插入名为 old_widget.gif 和 new_reenforced_widget.gif 的两个图像,即使文本受到保护,恶意人员也可以得知小部件正在升级的事实。使用通用图像文件名(例如 image1 和 image2)为 Office Open XML 格式文件添加了另一层保护。

    但是,您可以尝试(对于 Word 2007 文件,又名 XWPFDocument,又名“.docx”,其他 MS Office 文件的工作方式类似):

    try (FileInputStream fis = new FileInputStream("mydoc.docx")) {
        document = new XWPFDocument(fis);
        listEmbeds (document);
    }
    
    
    private static void listEmbeds (XWPFDocument doc) throws OpenXML4JException {
        List<PackagePart> embeddedDocs = doc.getAllEmbedds();
        if (embeddedDocs != null && !embeddedDocs.isEmpty()) {
            Iterator<PackagePart> pIter = embeddedDocs.iterator();
            while (pIter.hasNext()) {
                PackagePart pPart = pIter.next();
                System.out.print(pPart.getPartName()+", ");
                System.out.print(pPart.getContentType()+", ");
                System.out.println();
            }
        }
    }
    

    pPart.getPartName() 是我能找到的最接近嵌入文件的文件名。

    【讨论】:

      【解决方案2】:
      public class GetEmbedded {
      
          public static void main(String[] args) throws Exception {
              String path = "SomeExcelFile.xlsx"
              XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(new File(path)));
      
                   for (PackagePart pPart : workbook.getAllEmbedds()) {
                                  String contentType = pPart.getContentType();
                                  System.out.println("List of all the embedded contents in the Excel"+contentType);
                   }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-10
        • 1970-01-01
        • 2023-03-06
        • 1970-01-01
        • 2013-07-04
        相关资源
        最近更新 更多