Hi Jason,
I am trying to embed video/package into my docx file. I wonder how the OleObject.bin get created. Is docx4j support this, if so how do I generate the oleObject.bin file.
Please advice!
Thanks!
Betty
// 1. Load the Package
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));
// 2. Fetch the OLE document part
OleObjectBinaryPart olePart = (OleObjectBinaryPart)wordMLPackage.getParts().get(new PartName("/word/embeddings/oleObject1.bin") );
// 3. Write it
File f=new File("/home/dev/ole.bin");
FileOutputStream out=new FileOutputStream(f);
olePart.writeDataToOutputStream(out);
out.close();
// The object we embed
is = new java.io.FileInputStream("/home/dev/testing/fig1.pdf" );
OleObjectBinaryPart olePart = new OleObjectBinaryPart();
olePart.setBinaryData(is);
Relationship relOleObject = wordMLPackage.getMainDocumentPart().addTargetPart(olePart);
// The image the user sees, that they click on to open the object
Relationship relImage = wordMLPackage.getMainDocumentPart().addTargetPart(imagePart); // imagePart defined outside this snippet
// Contains ${ImageId}, ${OLEShapeID}, ${OLEObjectID}, ${OLEObjectRid}
String ml = "<w:p xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\"><w:r><w:object w:dxaOrig=\"11881\" w:dyaOrig=\"9181\"><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_i1025\" type=\"#_x0000_t75\" style=\"width:594pt;height:459pt\" o:ole=\"\"><v:imagedata r:id=\"${ImageId}\" o:title=\"\"/></v:shape><o:OLEObject Type=\"Embed\" ProgID=\"AcroExch.Document.7\" ShapeID=\"${OLEShapeID}\" DrawAspect=\"Content\" ObjectID=\"${OLEObjectID}\" r:id=\"${OLEObjectRid}\"/></w:object></w:r></w:p>";
java.util.HashMap<String, String>mappings = new java.util.HashMap<String, String>();
mappings.put("ImageId", relImage.getId() );
mappings.put("OLEShapeID", "_x0000_i1025" );
mappings.put("OLEObjectID", "_1291469606" );
mappings.put("OLEObjectRid", relOleObject.getId() );
wordMLPackage.getMainDocumentPart().addObject(
org.docx4j.XmlUtils.unmarshallFromTemplate(ml, mappings ) );
ContentTypeManager ctm = wordMLPackage.getContentTypeManager();
// There as an override, try adding as a default!
ctm.addDefaultContentType("bin",
org.docx4j.openpackaging.contenttype.ContentTypes.OFFICEDOCUMENT_OLE_OBJECT);
I have to commented out these 2 lines of code because it is given me an exception:
//((OleObjectBinaryPart)olePart).initPOIFSFileSystem();
//((OleObjectBinaryPart)olePart).writePOIFSFileSystem();
In this post, I am going to show you how to generate the IStorage and the image representing the embedded object by invoking the OLE Server associated with PDF files. To create the underlying data for a non-Office embedded object we need to look up the prog id of the application associated with the file format extension. To get this data we need to look under \HKCR\.XXX within the registry, where XXX is the file format extension (ex. PDF). Under this path you should see at least two sub keys: "(Default)" and "Content Type." The value specified for "(Default)" represents the prog id of the application associated with the file format. On my computer, the prog id associated with PDF files is "AcroExch.Document."
Since we don't know the structure of the embedded object we shouldn't use the content type associated with the file format extension. Instead, we should use the generic content type for embedded objects, which is "application/vnd.openxmlformats-officedocument.oleObject."
Our next step is to create the IStorage and an image representation for the embedded object. As mentioned in the Solution section above, we need to invoke the OLE Server associated with PDF files. Below is the C++ code needed to accomplish this task:
//********** This snippet is C++ code *************//
HRESULT PackageOleObject(LPCTSTR inputFile, LPCTSTR outputFile)
{
HRESULT hr = S_OK;
IStoragePtr pStorage = NULL;
IOleObjectPtr pOle = NULL;
IDataObjectPtr pdo = NULL;
FORMATETC fetc;
STGMEDIUM stgm;
HENHMETAFILE hmeta;
// Create a compound storage document.
hr = StgCreateStorageEx (
outputFile,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_TRANSACTED,
STGFMT_DOCFILE,
0,
NULL,
NULL,
IID_IStorage,
reinterpret_cast<void**>(&pStorage));
CheckHr(hr);
// Create OLE package from file.
hr = OleCreateFromFile(CLSID_NULL, inputFile, ::IID_IOleObject,
OLERENDER_NONE, NULL, NULL, pStorage, (void**)&pOle);
hr = OleRun(pOle);
CheckHr(hr);
hr = pOle->QueryInterface(IID_IDataObject, (void**)&pdo);
CheckHr(hr);
fetc.cfFormat = CF_ENHMETAFILE;
fetc.dwAspect = DVASPECT_CONTENT;
fetc.lindex = -1;
fetc.ptd = NULL;
fetc.tymed = TYMED_ENHMF;
stgm.hEnhMetaFile = NULL;
stgm.tymed = TYMED_ENHMF;
hr = pdo->GetData(&fetc, &stgm);
CheckHr(hr);
// Create image metafile for object.
CopyEnhMetaFile(stgm.hEnhMetaFile, emfFile);
hr = pStorage->Commit(STGC_DEFAULT );
CheckHr(hr);
pOle->Close(0);
DeleteEnhMetaFile(stgm.hEnhMetaFile);
DeleteEnhMetaFile(hmeta);
return hr;
}
The above C++ code snippet will create two output files that represent the IStorage and the image representation for our embedded object.
Users browsing this forum: No registered users and 86 guests