MacでcsvからExcelファイルを生成する(その2)EPPlus編
1 はじめに
昨日、「Windowsを使わないで、CSVからExcelを生成して、一部自動化」と言う事で、NPOIを紹介させて頂きました。
MacでcsvからExcelファイルを生成する(祝!本日公開のVisual Studio for Macを使ってみました)
しかし、Visual Studio for Mac 上から実行すると問題ないが、コマンドラインから実行すると、出力されるExcelファイルが、何故か0バイトになってしまうという問題に当たってしまいました。
本日は、比較試験も兼ねて、EPPulsで試してみました。 もちろん本日も、Visual Studio for Mac利用です。(今日はダークモード)
2 EPPlus
EPPlusもOpen XMLの仕様に基いてExcelデータを行うライブラリですが、Excel 2007より前のバージョン(xls)には、対応していません。
EPPlus-Create advanced Excel spreadsheets on the server
実は、ClosedXMLも試してみたのですが、こちらは、うまく動かすことが出来ませんでした。
Unhandled Exception: System.TypeInitializationException: The type initializer for 'System.Drawing.KnownColors' threw an exception. ---> System.TypeInitializationException: The type initializer for 'System.Drawing.GDIPlus' threw an exception. ---> System.DllNotFoundException: libgdiplus.dylib
3 作成手順
(1) プロジェクト作成
メニューから、ファイル > 新しいソリューションで新しいプロジェクトを作成しました。
名前は、ExcelGenelatorByEPPlusとしました。
(2) NuGetの追加
パッケージを追加しました。
NuGetライブラリでは、EPPlusで簡単に検索できます。
依存関係はなく、EPPlusのみがインストールされます。
(3) Excelファイルの準備
出力するExcelファイルは、罫線や書式を、予め作成しています。(金額や消費税などは、式で入っています)
sample.xlsx
(4) csvファイルの準備
差し込みに使うデータ(品名、数量、単価)は、csv形式で用意しました。
sample.csv
サーモン,5000,150 いか,5,200 さば,2,190 まぐろ,4,230 いるか,1,12000
(5) 実装
実装は、次のようになりました。 テンプレートのExcelファイルを開いて、Csvからデータを移して、新しいExcelファイルとして保存しています。
ちょっと注意が必要なのは、SheetやCellの配列が0からではなく1から指定することです。 なお、NPOIの時のように、再計算の処理は必要ありませんでした。
using System; using System.IO; using System.Reflection; using System.Linq; using OfficeOpenXml; namespace ExcelGenelator { class MainClass { public static void Main(string[] args) { //args = new String[] { "input.csv", "output.xlsx" }; // アプリケーションのフルパス var appPath = Assembly.GetExecutingAssembly().Location; if (args.Length != 2) { Console.WriteLine($"use: mono {Path.GetFileName(appPath)} input.csv output.xlsx"); return; } var appDirectory = Path.GetDirectoryName(appPath); // テンプレートExcel var templateExcelName = Path.Combine(appDirectory, "template.xlsx"); if (!File.Exists(templateExcelName)) { Console.WriteLine($"ERROR {templateExcelName} not Found."); return; } // 入力CSV var inputCsvName = Path.Combine(appDirectory, args[0]); if (!File.Exists(inputCsvName)) { Console.WriteLine($"ERROR {inputCsvName} not Found."); return; } // 出力Excel var outputExcelName = Path.Combine(appDirectory, args[1]); var wb = new ExcelPackage(new FileInfo(templateExcelName)); var sheet = wb.Workbook.Worksheets.First(); var lines = File.ReadAllLines(inputCsvName); foreach (var item in lines.Select((line, row) => new { line, row })) { var values = item.line.Split(','); foreach (int i in Enumerable.Range(0, 3)) { // データを差し込むのは7行目のカラム3個目以降(セル番号は、0からではなく1から指定) var cell = sheet.Cells[item.row + 8, i + 4]; if (i == 0) // 品名は、文字として挿入 { cell.Value = values[i]; } else { // 数量・単価は、数値として挿入 cell.Value = Int32.Parse(values[i]); } } //数式の再計算は必要ありません。 wb.SaveAs(new FileInfo(outputExcelName)); } } } }
4 動作確認
出力ファイルは、次のようになりました。今日も、サーモンは多い目です。
5 コマンドライン
Visual Studioで生成されるのは、exeファイルです。
コマンドラインから、次のように使用します。(第1パラメーター:入力CSV、第2パラメーター:出力ファイル)
$ mono ExcelGenelatorByEPPlus.exe input.csv output.xlsx
今回は、問題なくoutput.xlsxが出力されました。 もしかすると、MacでC#でExcelファイルを作るなら、EPPlus 一択かも知れません。>YOSHIEさん
6 最後に
NPOIの出力がmonoでうまく出せないのは、固有の問題のようです。XSSFWorkbookのWriteメソッドで直接ファイルストリームに書き出さずに、一旦、メモリ上に吐いてから、改めてファイル化したりすると上手くいくかも知れません。(すいません、未確認です)
EPPlusを使用する場合も、グラフやマクロなどは、正常に処理できません。また、残念ながら、印刷出力も出来ません。
[GitHub] https://github.com/furuya02/ExcelGenelatorByEPPlus
6 参考資料
EPPlusの基本的な使い方メモ (xlsx形式, Excelのインストール必要ない, COM使わない)
MacでcsvからExcelファイルを生成する(祝!本日公開のVisual Studio for Macを使ってみました)