この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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