MacでcsvからExcelファイルを生成する(祝!本日公開のVisual Studio for Macを使ってみました)
1 はじめに
身近で、「Windowsを使わないで、CSVからExcelファイルを生成して、一部自動化」みたいな作業があったので、ちょっとやってみました。 そして、ちょうど今日、Visual Studio for Mac(preview)も公開されたので、早速使って見ました。
Visual Studio for MAC のレビューは、今、ばりばり世界中で記事になっていると思うので・・・本記事は、単に使ってみただけです。(すいません)
2 NPOI
今回、使用させて頂いたのは、Apache POIの.NETへの移植版であるNPOIです。
Windows+Excelの環境では、COMの開放に注意が必要ですが、Microsoft.Office.Interop.Excelを使用するのが、最も自由に何でも出来る選択となるでしょう。
しかし、今回は、「Windowsを使わないで・・・」という事でしたので、いくつかのPOIを試してみた結果、一番すんなり動いたNPOIになりました。
Apache POIでは、HSSFとXSSFがありますが、Excel2007(.xlsx)以降では、XSSFを使用するようです。
3 作成手順
(1) プロジェクト作成
メニューから、ファイル > 新しいソリューションで新しいプロジェクトを作成しました。
名前は、ExcelGenelatorByNpioとしました。
(2) NuGetの追加
参照を追加しました。
NuGetライブラリでは、npoiで簡単に検索できます。
依存関係から、SharpZipLibと共に、インストールされます。
(3) Excelファイルの準備
出力するExcelファイルは、罫線や書式を、予め作成しておきます。 プログラムからも作業可能ですが、定形であれば、ある程度、先に作ってしまった方が簡単かと思いました。
なお、金額や消費税などは、予め式で入ってます。
sample.xlsx
(4) csvファイルの準備
差し込みに使うデータ(品名、数量、単価)は、csv形式で用意しました。
sample.csv
サーモン,5000,150 いか,5,200 さば,2,190 まぐろ,4,230 いるか,1,12000
(5) 実装
実装は、次のようになりました。 テンプレートのExcelファイルを開いて、Csvからデータを移して、新しいExcelファイルとして保存しています。
using System; using System.IO; using System.Reflection; using System.Linq; using NPOI.XSSF.UserModel; using NPOI.SS.UserModel; 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]); using (FileStream file = new FileStream(templateExcelName, FileMode.Open, FileAccess.ReadWrite)) { var wb = new XSSFWorkbook(file); ISheet sheet = wb.GetSheetAt(0); var lines = File.ReadAllLines(inputCsvName); foreach (var item in lines.Select((line, row) => new { line, row })) { // データを差し込むのは7行目以降 var row = sheet.GetRow(item.row + 7); var values = item.line.Split(','); foreach (int i in Enumerable.Range(0, 3)) { // データを差し込むカラムは3個目以降 var cell = row.GetCell(i + 3); if (i == 0) // 品名は、文字として挿入 { cell.SetCellValue(values[i]); } else { // 数量・単価は、数値として挿入 cell.SetCellValue(Int32.Parse(values[i])); } } } XSSFFormulaEvaluator.EvaluateAllFormulaCells(wb); // これで、数式を再計算します using (var fs = new FileStream(outputExcelName, FileMode.CreateNew)) { wb.Write(fs); } } } } }
4 動作確認
出力ファイルは、次のようになりました。ちょっとサーモンが多いです。
5 分からない・・・
Visual Studioで生成されるのは、exeファイルです。 実は、コマンドラインから、次のように使用したかったのですが・・・(第1パラメーター:入力CSV、第2パラメーター:出力ファイル)
$ mono ExcelGenelatorByNpio.exe input.csv output.xlsx
コマンドラインから実行すると、output.xlsxが0バイトになってしまいます。
Xamarin Studio でも同じでした。どなたかヒント下さい。m(.)m
2016/11/18追記
EPPlusは、出力できました。
MacでcsvからExcelファイルを生成する(その2)EPPlus編
6 最後に
今回使用した、NPOI以外にも、C#でExcelファイルを生成できるものとして次のようなものが有りました。そして、どちらも、NuGetからインストールが可能でした。
NPOIを使用する場合、Excelの機能である、グラフやマクロなどは、正常に処理できませんので注意が必要です。NPOIで処理できないセルは、無効となりますので、制約を充分確認してから作業する必要があります。また、残念ながら、印刷出力などはできません。
[GitHub] https://github.com/furuya02/ExcelGenelatorByNpio