ExcelファイルをPDFファイルに変換することはできるのでしょうか? Excelファイルを操作することができるライブラリとしてClosedXMLがあります。ExcelがインストールされていないパソコンでもExcelファイルを生成することができるのがClosedXMLの魅力です。
Contents
ClosedXMLではExcelファイルをPDFファイルに変換できない
ところがClosedXMLにはExcelファイルをPDFファイルに変換する機能はないそうです。そこで別の方法を考えます。調べてみると [C#]ExcelファイルからPDFファイル出力 などの記事がありました。これを参考にExcelファイルをPDFファイルに変換するアプリケーションを作成します。
ExcelファイルをPDFファイルに変換するクラスを自作する
まず、参照に「Microsoft Excel 16.0 Object Library]」を追加します。
Visual Studio の [プロジェクト] メニューの [参照の追加] で [参照 マネージャー] を表示して、[COM] – [Microsoft Excel 16.0 Object Library] にチェックして [OK] を押下します。
準備は以上です。それでははじめましょう。最初にコンストラクタにExcelファイルのパスと出力したいPDFファイルのパスを渡すとExcelファイルをPDFファイルに変換してくれるクラス ExcelFileToPdfクラスを作成します。
自作クラス ExcelFileToPdf
ExcelFileToPdfクラスのコンストラクタを示します。引数をフィールド変数に格納しているだけです。
1 2 3 4 5 6 7 8 9 10 11 |
public class ExcelFileToPdf { string ExcelFilePath = ""; string PdfFilePath = ""; public ExcelFileToPdf(string excelFilePath, string pdfFilePath) { ExcelFilePath = excelFilePath; PdfFilePath = pdfFilePath; } } |
SaveAsPDFメソッド
SaveAsPDFメソッドを示します。フィールド変数に格納したExcelFilePathとPdfFilePathからExcelファイルを読み取ってPDFファイルに変換します。このときExcelが起動しますが、ウィンドウは非表示にします。ユーザーからみれば突然Excelが起動するとなにが起きたのか分からず慌てて閉じてしまうかもしれません。これでは処理を続けることができないので裏でやってもらいます。
SaveAsPDFメソッドのなかでやることは以下の3つです。
Excelアプリケーションの生成
Bookを開く
Book内の全シートをPDF形式で保存する
ExportAsFixedFormatメソッドはブックを PDF または XPS 形式に変換して発行します。例外が発生する場合があるので例外処理をしています。
Marshal.ReleaseComObjectで後始末
それから処理が終わったら終了処理をおこなっています。_applicationと_workbookはCOM オブジェクトなので
Close()やQuit()するだけではダメです。Marshal.ReleaseComObjectメソッドを使用して適時に解放しなければなりません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
public class ExcelFileToPdf { private Microsoft.Office.Interop.Excel.Application _application = null; private Workbook _workbook = null; public bool SaveAsPDF() { if (!File.Exists(ExcelFilePath)) return false; try { // Excelアプリケーション生成(ただしWindowsは非表示) _application = new Microsoft.Office.Interop.Excel.Application() { Visible = false, }; // Bookを開く _workbook = _application.Workbooks.Open(ExcelFilePath); // 全シートを選択する _workbook.Worksheets.Select(); // ファイル名を指定してPDF形式で保存する _workbook.ExportAsFixedFormat( Type: XlFixedFormatType.xlTypePDF, // XlFixedFormatType.xlTypeXPSにすればXPS形式に Filename: PdfFilePath, // 出力ファイル名 Quality: XlFixedFormatQuality.xlQualityStandard // 出力品質=標準品質 ); } catch { return false; } finally { if (_workbook != null) { _workbook.Close(); Marshal.ReleaseComObject(_workbook); _workbook = null; } if (_application != null) { _application.Quit(); Marshal.ReleaseComObject(_application); _application = null; } } return true; } } |
ExcelFileToPdfクラスを使ってExcelファイルをPDFファイルに変換する
ExcelFileToPdfクラスが完成したらあとはこれをつかってExcelファイルをPDFファイルに変換するだけです。
ボタンをクリックすると変換元のExcelファイルを開くためのダイアログと返還後のPDFファイルを保存する場所を指定するためのダイアログが現れます。ふたつのダイアログでファイルのパスを指定したらExcelFileToPdfのコンストラクタにこれらが渡されます。しばらく待つと処理の結果が表示されます。
ExcelFileToPdf.SaveAsPDFメソッドがfalseを返す場合として、Excelファイルが存在しない、Excelファイルの中身が空などの理由が考えられます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { string excelFile = ""; OpenFileDialog open = new OpenFileDialog(); open.Filter = "Excelファイル(*.xlsx)|*.xlsx|すべてのファイル(*.*)|*.*"; if (open.ShowDialog() == DialogResult.OK) excelFile = open.FileName; open.Dispose(); if (excelFile == "") return; string pdfFile = ""; SaveFileDialog save = new SaveFileDialog(); save.Filter = "PFDファイル(*.pdf)|*.pdf|すべてのファイル(*.*)|*.*"; if (save.ShowDialog() == DialogResult.OK) pdfFile = save.FileName; save.Dispose(); if (pdfFile == "") return; ExcelFileToPdf excelFileToPdf = new ExcelFileToPdf(excelFile, pdfFile); bool ret = excelFileToPdf.SaveAsPDF(); if (ret) MessageBox.Show("処理は完了しました", "報告", MessageBoxButtons.OK, MessageBoxIcon.Information); else MessageBox.Show("エラーが発生しました", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); } } |
closedXmlはExcelのコンポーネントを使用せずにExcelを操作しているので、pdf化についてもExcel参照に頼らずする方法が知りたかったです。