0

PDF ファイルを OPEN XML ドキュメントに埋め込もうとしています。これには、*.bin ファイルを作成する必要があります。自動化は使いたくない。

この質問から取ったアプローチは、*.pdf を除く、テストしたすべてのファイル タイプで機能します。

何らかの理由で、pdf ファイルは常に OleCreateFromFile(..) から 0x80004005 の結果を取得し、pOle は NULL になります。

私は、呼び出しと OLE の分野では初めてです。このアプローチが PDF で機能しない理由は何でしょうか? (最新の Adob​​e 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();
        }
4

1 に答える 1

0

実際に OpenXML にファイルを埋め込むには、古き良き OLE 関数を使用する必要があります。2 つのピースを取得する必要があるため、他に方法はありません。

  • 埋め込むファイル
  • ファイルの内容を示す画像、通常は最初のページのスクリーンショット

私はそれについてのブログエントリを書きました: Embedd pdf into powerpoint by usage of openxml。これは正確な要件ではありませんが、同じように機能します。

埋め込みに関しては、pdf には 2 つの問題があります。

  • 埋め込まれた PDF ドキュメントには、元の PDF ファイルとは異なるコンテンツが含まれています。私が知っている他のすべての OLE 形式 (excel、word、powerpoint など) では、これは当てはまりません。ハードディスク上のファイルをそのまま使用できますが、pdf の場合は使用できません。
  • 最初のページの写真を撮る必要があります。pdfium などを使用できます。pdf をレンダリングするためのツールはかなりありますが、Adobe Reader は無料で、100% ジョブを実行します。
于 2016-04-04T14:33:32.210 に答える