阅读Excel并获取嵌入式对象的行号和文件扩展名

时间:2019-02-20 01:41:40

标签: java apache-poi

我在我的应用程序中将Apache POI与Jav​​a 1.8一起使用。在我的应用程序中,我尝试读取Excel并获取嵌入式对象。

我需要知道如何获取每个嵌入式OLE对象的行号和文件扩展名。

Workbook workbook = WorkbookFactory.create(new File(path));

XSSFWorkbook fWorkbook = (XSSFWorkbook) workbook;

List<PackagePart> embeddedDocs = fWorkbook.getAllEmbedds();

获取embeddedDocs.getContentType,它返回application/vnd.openxmlformats-officedocument.oleObject

但是无论如何,我们都可以获取MimeType返回的文件扩展名(即pdf,ppt,mp3)。以及哪种方式获取嵌入对象的行数。解决这个问题的任何想法/编码逻辑将非常有用。

1 个答案:

答案 0 :(得分:0)

以下内容适用于-我想-通常的嫌疑犯。我已经在POI中继上使用.xls / x对其进行了测试,这将是POI 4.1.0,但也应该可以在POI 4.0.1中使用。

已知问题是:

  • 对象不是基于文件嵌入的,因此您没有文件名。这可能也适用于大多数.xls文件。

  • .xlsx仅包含vmlDrawing * .xml,因此无法提取DrawingPatriach并且无法确定形状

  • .xlsx中的形状不是通过twoCellAnchor锚定的,那么您就不会获得ClientAnchor

代码:

import java.io.FileInputStream;
import java.io.IOException;

import org.apache.poi.hpsf.ClassIDPredefined;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.ss.usermodel.ChildAnchor;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.ObjectData;
import org.apache.poi.ss.usermodel.Shape;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.junit.Test;

public class TestEmbed {
    @Test
    public void extract() throws IOException {
//        String xlsName = "test-data/spreadsheet/WithEmbeddedObjects.xls";
        String xlsName = "embed.xlsx";
        try (FileInputStream fis = new FileInputStream(xlsName);
             Workbook xls = WorkbookFactory.create(fis)) {
            for (Sheet s : xls) {
                Drawing<?> dp = s.getDrawingPatriarch();
                if (dp != null) {
                    for (Shape sh : dp) {
                        if (sh instanceof ObjectData) {
                            ObjectData od = (ObjectData)sh;
                            String filename = od.getFileName();
                            String ext = null;

                            if (filename != null && !filename.isEmpty()) {
                                int i = filename.lastIndexOf('.');
                                ext = (i > 0) ? filename.substring(i) : ".bin";
                            } else {
                                String ct = null;

                                try {
                                    DirectoryEntry de = od.getDirectory();

                                    if (de != null) {
                                        ClassIDPredefined ctcls = ClassIDPredefined.lookup(de.getStorageClsid());
                                        if (ctcls != null) {
                                            ext = ctcls.getFileExtension();
                                        }
                                    }
                                } catch (Exception ignore) {
                                }
                            }

                            if (ext == null) {
                                ext = ".bin";
                            }

                            ChildAnchor chAnc = sh.getAnchor();
                            if (chAnc instanceof ClientAnchor) {
                                ClientAnchor anc = (ClientAnchor) chAnc;
                                System.out.println("Rows: " + anc.getRow1() + " to " + anc.getRow2() + " - filename: "+filename+" - ext: "+ext);
                            }
                        }
                    }
                }
            }
        }
    }
}