Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java在excel中读取嵌入的pdf文件_Java_Pdf_Apache Poi_Pdfbox - Fatal编程技术网

使用Java在excel中读取嵌入的pdf文件

使用Java在excel中读取嵌入的pdf文件,java,pdf,apache-poi,pdfbox,Java,Pdf,Apache Poi,Pdfbox,我是Java编程新手。我当前的项目要求我读取excel工作表中的嵌入(ole)文件并获取其中的文本内容。阅读嵌入式word文件的示例效果很好,但是我无法找到阅读嵌入式pdf文件的帮助。通过看类似的例子,尝试了一些事情。。。。但没有成功 我有下面的代码,也许在帮助下我能找到正确的方向。我使用ApachePOI读取excel和pdfbox中的嵌入文件来解析pdf数据 public class ReadExcel1 { public static void main(String[] args)

我是Java编程新手。我当前的项目要求我读取excel工作表中的嵌入(ole)文件并获取其中的文本内容。阅读嵌入式word文件的示例效果很好,但是我无法找到阅读嵌入式pdf文件的帮助。通过看类似的例子,尝试了一些事情。。。。但没有成功

我有下面的代码,也许在帮助下我能找到正确的方向。我使用ApachePOI读取excel和pdfbox中的嵌入文件来解析pdf数据

public class ReadExcel1 {

public static void main(String[] args) {

    try {

        FileInputStream file = new FileInputStream(new File("C:\\test.xls"));

        POIFSFileSystem fs = new POIFSFileSystem(file);
        HSSFWorkbook workbook = new HSSFWorkbook(fs);

        for (HSSFObjectData obj : workbook.getAllEmbeddedObjects()) {

            String oleName = obj.getOLE2ClassName();

           if(oleName.equals("Acrobat Document")){
                System.out.println("Acrobat reader document");

                try{
                    DirectoryNode dn = (DirectoryNode) obj.getDirectory();
                    for (Iterator<Entry> entries = dn.getEntries(); entries.hasNext();) {

                        DocumentEntry nativeEntry = (DocumentEntry) dn.getEntry("CONTENTS");
                        byte[] data = new byte[nativeEntry.getSize()];

                        ByteArrayInputStream bao= new ByteArrayInputStream(data);
                        PDFParser pdfparser = new PDFParser(bao);

                        pdfparser.parse();
                        COSDocument cosDoc = pdfparser.getDocument();
                        PDFTextStripper pdfStripper = new PDFTextStripper();
                        PDDocument pdDoc = new PDDocument(cosDoc);
                        pdfStripper.setStartPage(1);
                        pdfStripper.setEndPage(2);
                        System.out.println("Text from the pdf "+pdfStripper.getText(pdDoc));
                    }
                }catch(Exception e){
                    System.out.println("Error reading "+ e.getMessage());
                }finally{
                    System.out.println("Finally ");
                }
            }else{
                System.out.println("nothing ");
            }
        }

        file.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
读取错误:文件结尾,应为行 最后
没有什么

PDF不是OLE 1.0打包的,但以某种方式嵌入了不同的内容-至少提取对我来说是有效的。 这不是一个通用的解决方案,因为它取决于嵌入应用程序如何命名条目。。。当然,对于PDF,您可以检查所有
DocumentNode
-s中的幻数“%PDF”-对于OLE 1.0打包元素,这需要以不同的方式完成

我认为,pdf的真实文件名隐藏在
\1Ole
CompObj
条目中的某个地方,但对于示例和您的用例来说,这显然是不需要确定的

import java.io.*;
import java.net.URL;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.*;
import org.apache.poi.util.IOUtils;

public class EmbeddedPdfInExcel {
    public static void main(String[] args) throws Exception {
        NPOIFSFileSystem fs = new NPOIFSFileSystem(new URL("http://jamesshaji.com/sample.xls").openStream());
        HSSFWorkbook wb = new HSSFWorkbook(fs.getRoot(), true);
        for (HSSFObjectData obj : wb.getAllEmbeddedObjects()) {
            String oleName = obj.getOLE2ClassName();
            DirectoryNode dn = (DirectoryNode)obj.getDirectory();
            if(oleName.contains("Acro") && dn.hasEntry("CONTENTS")){
                InputStream is = dn.createDocumentInputStream("CONTENTS");
                FileOutputStream fos = new FileOutputStream(obj.getDirectory().getName()+".pdf");
                IOUtils.copy(is, fos);
                fos.close();
                is.close();
            }
        }
        fs.close();
    }
}

第一件看起来很奇怪的事情是
dn.getEntry(“CONTENTS”)
-PDF应该位于名为
MBD…
(有关更多详细信息,请参阅)的DirectoryNode中。。。我猜,你正在访问一些空流。。。你能提供一个示例Excel文件吗?!你读过?@kiwiwings了吗?我确实在DirectoryNode中看到了“MBD”条目,其中没有任何数据。dn.getEntry(“CONTENTS”)为我提供了大小超过10000的数据,因此假设在该特定条目中有可用的数据。@James Shaji如果您要上传一个示例文件,我可以获得。如果您从HSSFObjectData获取数据而无需进一步处理,或者必须使用POIFS条目来检索数据,我将不得不尝试。此外,嵌入式对象和(OLE 1.0)打包对象之间可能存在差异,因此使用真实文件(而不仅仅是理论提示…)更容易找到它们。@kiwiwings我已将excel表上载到感谢kiwiwings!!我在哪里可以找到帮助我理解文件结构的文档?你真的想通读MS规范吗???有两个规格需要检查:,对于其他office格式,您可以在第二个链接附近找到规格
import java.io.*;
import java.net.URL;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.*;
import org.apache.poi.util.IOUtils;

public class EmbeddedPdfInExcel {
    public static void main(String[] args) throws Exception {
        NPOIFSFileSystem fs = new NPOIFSFileSystem(new URL("http://jamesshaji.com/sample.xls").openStream());
        HSSFWorkbook wb = new HSSFWorkbook(fs.getRoot(), true);
        for (HSSFObjectData obj : wb.getAllEmbeddedObjects()) {
            String oleName = obj.getOLE2ClassName();
            DirectoryNode dn = (DirectoryNode)obj.getDirectory();
            if(oleName.contains("Acro") && dn.hasEntry("CONTENTS")){
                InputStream is = dn.createDocumentInputStream("CONTENTS");
                FileOutputStream fos = new FileOutputStream(obj.getDirectory().getName()+".pdf");
                IOUtils.copy(is, fos);
                fos.close();
                is.close();
            }
        }
        fs.close();
    }
}