/ .NET, C#

Offce2007以降、PDF形式へのエクスポートが標準でサポートされるようになりました。
というわけで、.NETアプリケーションからOfficeファイルのPDFエクスポートを実行する方法を紹介したいと思います。

静的な参照設定を行う場合は、必要なOfficeアプリのObject Libraryを参照設定しておいて、普通にVBAオブジェクトを.NETアプリから操作すれば良いわけですが、これだとそもそもOffice2007以降がインストールされていないPCでは参照エラーで正常動作しません。

そこで登場するのが遅延バインディング(Late Binding)という方法。
論より証拠、Excel→PDF変換のサンプルコードを載せておきます。

Word、PowerPointについても同様のイメージで実装できますが、Officeアプリによってそれぞれライブラリ仕様が異なりますので、流用できるのは基本的な流れ(アプリインスタンス作成→ファイルオープン→エクスポート→クローズ)だけになります。
そのため、少し面倒ですが、各OfficeアプリのMSDN Developer Referenceなどを参照してプロパティやメソッドの利用方法を調べつつ、実装していく必要があります。
VBAのオブジェクトをインテリセンス無しに記述して操作することになるので、とにかくパラメータの数や位置に注意が必要です。
リファレンス無しではまず作れないわけですが、どうも英語の資料しかなさげなのが厳しいところです。

public bool Excel2Pdf(string sourcePath, string targetPath)
{
	const int xlTypePDF = 0;
	const int xlQualityStandard = 0;

	bool result = false;
	object missing = Type.Missing;

	object excel = null;
	object workbooks = null;
	object workbook = null;

	try
	{
		excel = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));

		if (excel != null)
		{
			workbooks = excel.GetType().InvokeMember("Workbooks", BindingFlags.GetProperty, null, excel, null);

			if (workbooks != null)
			{
				workbook = workbooks.GetType().InvokeMember("Open", BindingFlags.InvokeMethod, null, workbooks,
					new object[]
					{
						sourcePath, missing, true, missing, missing, missing,
						missing, missing, missing, missing, missing, missing, missing, missing, missing
					}, null);

				if (workbook != null)
				{
					workbook.GetType().InvokeMember("ExportAsFixedFormat", BindingFlags.InvokeMethod, null, workbook,
						new object[]
						{
							xlTypePDF, targetPath, xlQualityStandard, true, false, missing, missing, missing, missing
						}, null);
					result = true;
				}
			}
		}
	}
	catch
	{
	}
	finally
	{
		if (workbook != null)
		{
			workbook.GetType().InvokeMember("Close", BindingFlags.InvokeMethod, null, workbook,
				new object[]
				{
					false, missing, missing
				}, null);
			workbook = null;
		}
		if (workbooks != null)
			workbooks = null;
		if (excel != null)
		{
			excel.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, excel, null, null);
			excel = null;
		}
		GC.Collect();
		GC.WaitForPendingFinalizers();
		GC.Collect();
		GC.WaitForPendingFinalizers();
		GC.Collect();
		GC.WaitForPendingFinalizers();
	}
	return result;
}

ここでは単純にOK/NGを返すだけのメソッドになっていますが、実際にはエラー処理などの追加が必要になるかと思います。
また、パスワードロックされているOffice文書を開いた場合など、変換処理中にOfficeのウィンドウが表示されることがあるのですが、そのウィンドウが前面表示されないために操作感が悪くなってしまうケースが見受けられました。
これについては、Win32APIのFindWindow+SetForegroundWindowメソッドで最前面表示する手法を使うことによって回避できるようです。



コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です