2013-07-17 66 views
0

我想將pdf文件嵌入到OPEN XML文檔中。這需要創建* .bin文件。我不想使用自動化。通過OleCreateFromFile在C#中調用OLE不適用於pdf文件

Ive採取的方法this question適用於除* .pdf外的所有文件類型。

由於某些原因,pdf文件總是從OleCreateFromFile(..)得到結果爲0x80004005,而pOle爲NULL。

我是調用和OLE領域的新手。這種方法不適用於PDF的原因是什麼? (我有最新的Adobe Reader,Win8,調用Ole32.dll,項目構建目標是x86,我測試調用CoUninitialize()和CoInitializeEx((System.IntPtr)null,OLE32.CoInit.ApartmentThreaded),我能夠在MSWORD應用程序中嵌入pdf文件)。

這裏是我使用它的功能:

public static string ExportOleFile(string _inputFileName, string oleOutputFileName, string emfOutputFileName) 
     { 
      StringBuilder resultString = new StringBuilder();   
      string newInput = MultibyteToUnicodeNETOnly(_inputFileName, 1252); 

      Microsoft.VisualStudio.OLE.Interop.IStorage storage; 
      var result = OLE32.StgCreateStorageEx(oleOutputFileName, 
       Convert.ToInt32(OLE32.STGM.STGM_READWRITE | OLE32.STGM.STGM_SHARE_EXCLUSIVE | OLE32.STGM.STGM_CREATE | OLE32.STGM.STGM_TRANSACTED), 
       Convert.ToInt32(OLE32.STGFMT.STGFMT_DOCFILE), 
       0, 
       IntPtr.Zero, 
       IntPtr.Zero, 
       ref OLE32.IID_IStorage, 
       out storage 
      );//vytvoří bin 

      resultString.AppendLine("CreateStorageEx Result: " + result.ToString()); 

      var CLSID_NULL = Guid.Empty; 


      Microsoft.VisualStudio.OLE.Interop.FORMATETC f = new FORMATETC(); 
      Microsoft.VisualStudio.OLE.Interop.IOleObject pOle; 
      result = OLE32.OleCreateFromFile(
       ref CLSID_NULL, 
       newInput, 
       ref OLE32.IID_IOleObject, 
       (uint)Microsoft.VisualStudio.OLE.Interop.OLERENDER.OLERENDER_NONE, 
       ref f, 
       null, 
       storage, 
       out pOle 
      ); 

      resultString.AppendLine("OleCreateFromFile Result: " + result.ToString()); 
      try 
      { 

       result = OLE32.OleRun(pOle); 
      } 
      catch (Exception ex) 
      { 
       resultString.AppendLine(ex.ToString()); 
       return resultString.ToString(); 
      } 

      resultString.AppendLine("OleRun Result: " + result.ToString()); 

      try 
      { 

       IntPtr unknownFromOle = Marshal.GetIUnknownForObject(pOle); 
       IntPtr unknownForDataObj; 
       Marshal.QueryInterface(unknownFromOle, ref OLE32.IID_IDataObject, out unknownForDataObj); 
       var pdo = Marshal.GetObjectForIUnknown(unknownForDataObj) as System.Runtime.InteropServices.ComTypes.IDataObject; 

       var fetc = new System.Runtime.InteropServices.ComTypes.FORMATETC(); 

       fetc.cfFormat = (short)OLE32.CLIPFORMAT.CF_ENHMETAFILE; 
       fetc.dwAspect = System.Runtime.InteropServices.ComTypes.DVASPECT.DVASPECT_CONTENT; 
       fetc.lindex = -1; 
       fetc.ptd = IntPtr.Zero; 
       fetc.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_ENHMF; 

       var stgm = new System.Runtime.InteropServices.ComTypes.STGMEDIUM(); 
       stgm.unionmember = IntPtr.Zero; 
       stgm.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_ENHMF; 
       pdo.GetData(ref fetc, out stgm); 

       var hemf = GDI32.CopyEnhMetaFile(stgm.unionmember, emfOutputFileName); 
       storage.Commit((int)OLE32.STGC.DEFAULT); 

       pOle.Close(0); 
       GDI32.DeleteEnhMetaFile(stgm.unionmember); 
       GDI32.DeleteEnhMetaFile(hemf); 
      } 
      catch (Exception ex) 
      { 
       resultString.AppendLine(ex.ToString()); 
       return resultString.ToString(); 
      }   
      return resultString.ToString(); 
     } 
+0

使用古老而沉重過時的API,而這由另一家公司擁有的應該是麻煩的一個文件格式的組合。如果你不想使用自動化,那麼至少應該使用openxml api。 –

+0

您能否給我提供一個如何使用Open XML API將PDF(或任何文件格式除外的圖像)嵌入Word文檔的例子?我不想使用自動化。 – aerkain

回答

0

其實在OpenXML的嵌入文件,就必須用好老OLE功能工作。周圍有沒有其他辦法,因爲你需要得到兩件:

  • 那將是嵌入式
  • 的圖片,顯示了文件的內容,通常是第一頁的截圖文件

我寫了一篇關於該文章的博客文章:Embedd pdf into powerpoint by usage of openxml。這不完全是你的要求,但它的作用是一致的。

沒有與PDF的兩個問題,當談到嵌入:

  • 嵌入PDF文檔具有比原始PDF文件不同的內容。對於我所知道的所有其他OLE格式(excel,word,powerpoint,...),情況並非如此。您可以在硬盤上使用該文件,而不能使用pdf。
  • 您需要拍攝第一頁的照片。你可以使用pdfium或類似的東西 - 有很多工具可以用來渲染PDF,但Adobe Reader是免費的,並且可以完成100%的工作。
相關問題