当前位置: 首页 > 知识库问答 >
问题:

Apache POI库:如何读取嵌入Word文档中的Excel表

陈龙野
2023-03-14

OOXML包含以下代码:

<w:object w:dxaOrig="6942" w:dyaOrig="3234" w14:anchorId="071813E3">
                <v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
                  <v:stroke joinstyle="miter"/>
                  <v:formulas>
                    <v:f eqn="if lineDrawn pixelLineWidth 0"/>
                    <v:f eqn="sum @0 1 0"/>
                    <v:f eqn="sum 0 0 @1"/>
                    <v:f eqn="prod @2 1 2"/>
                    <v:f eqn="prod @3 21600 pixelWidth"/>
                    <v:f eqn="prod @3 21600 pixelHeight"/>
                    <v:f eqn="sum @0 0 1"/>
                    <v:f eqn="prod @6 1 2"/>
                    <v:f eqn="prod @7 21600 pixelWidth"/>
                    <v:f eqn="sum @8 21600 0"/>
                    <v:f eqn="prod @7 21600 pixelHeight"/>
                    <v:f eqn="sum @10 21600 0"/>
                  </v:formulas>
                  <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
                  <o:lock v:ext="edit" aspectratio="t"/>
                </v:shapetype>
                <v:shape id="_x0000_i1037" type="#_x0000_t75" style="width:347.4pt;height:162pt" o:ole="">
                  <v:imagedata r:id="rId7" o:title=""/>
                </v:shape>
                <o:OLEObject Type="Embed" ProgID="Excel.Sheet.12" ShapeID="_x0000_i1037" DrawAspect="Content" ObjectID="_1653752874" r:id="rId8"/>
              </w:object>

我看到里面嵌着OLEObject。但不确定如何阅读它的内容。非常感谢任何帮助。

共有1个答案

公冶光亮
2023-03-14

OleObject包含在xwpfrun中。因此可以检查每个xwpfrun是否包含oleObject。如果是,那么从OleObject中获取rid属性。此ID链接到Office Open XML文档的文档部分。该文档部分后面的包部分的内容类型决定了嵌入的对象类型。因此,根据内容类型,可以获得XSSFWorkbookHSSFWorkbook或其他嵌入的OleObject

以下方法演示了这种方法:

...
import org.apache.poi.ooxml.*;
import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.hssf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.apache.xmlbeans.XmlObject;
...

 void handleOLEObjects(XWPFRun run) {
  CTR ctr = run.getCTR();
  String declareNameSpaces = "declare namespace o='urn:schemas-microsoft-com:office:office'";
  XmlObject[] oleObjects = ctr.selectPath(declareNameSpaces + ".//o:OLEObject");
  for (XmlObject oleObject : oleObjects) {
   XmlObject rIdAttribute = oleObject.selectAttribute("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id");
   if (rIdAttribute != null) {
    String rId = rIdAttribute.newCursor().getTextValue();
    handleOLEObject(run.getDocument(), rId);
   }
  }
 }

 void handleOLEObject(XWPFDocument document, String rId) {
  POIXMLDocumentPart documentPart = document.getRelationById(rId);
  if ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".equals(documentPart.getPackagePart().getContentType())) {
   handleXSSFWorkbook(documentPart.getPackagePart());
  } else if ("application/vnd.ms-excel".equals(documentPart.getPackagePart().getContentType())) {
   handleHSSFWorkbook(documentPart.getPackagePart());
  } //else if ...
 }

 void handleXSSFWorkbook(PackagePart part) {
  try {
   XSSFWorkbook workbook = new XSSFWorkbook(part);
   for (Sheet sheet : workbook) {
    for (Row row : sheet) {
     for (Cell cell : row) {
      System.out.print(cell + "\t");
     }
     System.out.println();
    }
   }
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 }

 void handleHSSFWorkbook(PackagePart part) {
  try {
   HSSFWorkbook workbook = new HSSFWorkbook(part.getInputStream());
   for (Sheet sheet : workbook) {
    for (Row row : sheet) {
     for (Cell cell : row) {
      System.out.print(cell + "\t");
     }
     System.out.println();
    }
   }
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 }

方法HandleOleObjects使用XPathXWPfrun中获取所有OleObjectXML对象。它还获取rid属性。如果存在这样的对象,则调用HandleOleObject。此方法通过RIDXWPFDocument获取链接的POIXMLDocumentPart。然后,它根据内容类型确定嵌入了哪些OleObjects类型,并为这些对象调用不同的处理程序方法。

 类似资料:
  • 我正在尝试创建一个包含多列的word文档。这样做(而不是使用表)的原因是,数据将跨越多个页面,在添加到新页面之前,我只能用列填充整个页面。 可以用ApachePOI实现吗?谢谢

  • 在我的项目中,我有一个显示Word文档页数的要求。doc,。docx)文件和Excel文档中的工作表数量(。xls,。xlsx)。我试着去阅读。docx文件使用Docx4j,但性能很差,但我只需要字数,并尝试使用Apache POI。我得到一个错误,类似于: 我想知道是否有任何付费/开源库可用于Android。

  • 我需要一个表格,第一行和第二行的单元格合并在一起。 大概是这样的: 桌子的图片(我不能张贴图片)http://i.stack.imgur.com/dAO6j.png 我一直在复习与本主题相关的所有问题,并找到了一些将网格跨度应用于单元的答案,但我找不到真正的解决方案。 以下是我从谷歌和本网站获得的示例代码: 我从这段代码中得到的信息如下: 我试图用

  • 嗨,我想在第一行搜索一个字符串,如果找到了,我想移动那一列。

  • 我正在写一个程序,它需要从excel文件中读取和写入数据,而不考虑格式(xls或xlsx)。 我知道ApachePOI,但它似乎有不同的类来处理xls文件(HSSF)和xlsx(XSSF)文件。 任何人都知道我将如何实现我在这里的目标。(也欢迎使用POI以外的API的想法)。

  • 第一次使用python。我正在尝试浏览包含段落和表格的word文档。我已经弄清楚了如何使用以下代码浏览文档中的所有段落和文档中的所有表格: 但我正试图找到一种方法,像任何阅读它的人一样,有序地浏览这份文件。所以如果我们有一份文件包含: 它会按照这个顺序读。我想这样做的原因是,根据表格后面的段落,我想对它执行不同的操作。