ちょっと話題の記事

MacでcsvからExcelファイルを生成する(祝!本日公開のVisual Studio for Macを使ってみました)

2016.11.17

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

1 はじめに

身近で、「Windowsを使わないで、CSVからExcelファイルを生成して、一部自動化」みたいな作業があったので、ちょっとやってみました。 そして、ちょうど今日、Visual Studio for Mac(preview)も公開されたので、早速使って見ました。

Visual Studio for MAC のレビューは、今、ばりばり世界中で記事になっていると思うので・・・本記事は、単に使ってみただけです。(すいません)

010

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) プロジェクト作成

メニューから、ファイル > 新しいソリューションで新しいプロジェクトを作成しました。

001

名前は、ExcelGenelatorByNpioとしました。

002

(2) NuGetの追加

参照を追加しました。

003

NuGetライブラリでは、npoiで簡単に検索できます。

007

依存関係から、SharpZipLibと共に、インストールされます。

011

(3) Excelファイルの準備

出力するExcelファイルは、罫線や書式を、予め作成しておきます。 プログラムからも作業可能ですが、定形であれば、ある程度、先に作ってしまった方が簡単かと思いました。

なお、金額や消費税などは、予め式で入ってます。

sample.xlsx

004

(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 動作確認

出力ファイルは、次のようになりました。ちょっとサーモンが多いです。

009

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からインストールが可能でした。

012

013

NPOIを使用する場合、Excelの機能である、グラフやマクロなどは、正常に処理できませんので注意が必要です。NPOIで処理できないセルは、無効となりますので、制約を充分確認してから作業する必要があります。また、残念ながら、印刷出力などはできません。


github [GitHub] https://github.com/furuya02/ExcelGenelatorByNpio

7 参考資料


Apache POIでExcelを操作
かずきのBlog@hatena NPOI入門してみた