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

问题描述 投票:0回答:1

我正在使用Apache POI库来读取一个Word文档并将其转换为HTML。我有一个Word文档,其中包含一个嵌入式Excel工作表。有什么方法可以在读取XWPF文档时读取那个嵌入的Excel表格吗?

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. 但不知道如何读取其内容。任何帮助都是非常感激的。

java excel apache-poi word
1个回答
1
投票

OLEObject中包含了 XWPFRuns. 所以可以检查每个 XWPFRun 是否包含 OLEObjects. 如果是这样,那么得到的 rId 的属性 OLEObject. 这个ID链接到一个文件的一部分。Office Open XML 文档。该文档部分后面的包部分的内容类型决定了嵌入的对象是什么类型。因此,根据内容类型的不同,我们可以得到的是 XSSFWorkbook, HSSFWorkbook 或其他嵌入式 OLEObjects则。

下面的方法展示了这种方法。

...
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 用途 XPath 以获得所有 OLEObject XML 脱离 XWPFRun. 它还得到了 rId 属性。如果存在这样的属性,那么它就会调用 handleOLEObject. 本方法获取链接的 POIXMLDocumentPartXWPFDocumentrId. 然后,它通过内容类型来决定哪些种类的内容。OLEObjects 并为这些对象调用不同的处理方法。

© www.soinside.com 2019 - 2024. All rights reserved.