[C#]NPOIを使ってExcelの読み書きをする方法
- 2017/9/17
- C#
- ExcelをC#で読み書きする, NPOI
- 2 comments
NPOIを使ってExcelの読み書きをする方法
NPOIとは
ざっくりとした説明だが、「Apache POI」というWordやExcelのファイルを読み書きするためのJavaライブラリを、「.NET」に移植したものらしい。
私も、「Microsoft Office XX.X Object Library」を使うものだと思っていたが、ネットにはこのライブラリについて批判的な情報が多い。
実際にNPOIに慣れるとこちらのほうが簡単だと思う。
NPOIのインストール
NPOIは「Visual Studio Community(私の環境は2017)」で、プロジェクトごとにインストールする。
次の手順でインストールすると、参照設定も自動で必要な分行われる。
NuGetパッケージマネージャ
メニューから
「ツール」→「NuGetパッケージマネージャ」→「パッケージマネージャーコンソール」を開く。
すると、「パッケージマネージャーコンソール」ウィンドウが開き、下図のように、コマンドプロンプトが表示される。
赤字を入力してEnterキーを押す。
「PM> Install-Package NPOI」
これで「正常にインストールされました」とメッセージが表示され。
「PM>」というプロンプトが出たら「パッケージマネージャーコンソールウィンドウ」を閉じる。
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // ここから追加 using System.IO; // FileStreamを使用するため using NPOI.SS.UserModel; // NPOI namespace ExcelNNpoiSample { class Program { static void Main(string[] args) { try { #region 初期設定と宣言 /* * 文字リテラルの前に「@」をつけると * 「\」はエスケープシーケンスとみなされなくなります。 * ファイルのパスなどによく使われます。 */ // Excelのファイルパス string readPath = @"C:\test\Excel1.xlsx"; string writePath = @"C:\test\Excel2.xlsx"; // ファイル取得用 FileStream fs = null; // ブック格納用 IWorkbook readBook = null; IWorkbook writeBook = null; // データ受け渡し用変数 List<ExcelData> dataList = new List<ExcelData>(); ExcelData data = null; #endregion #region ファイル読み込み // 読込用Excelファイルの読込 using (fs = File.OpenRead(readPath)) { readBook = WorkbookFactory.Create(fs); } // 書込用Excelファイルの読込 using (fs = File.OpenRead(writePath)) { writeBook = WorkbookFactory.Create(fs); } #endregion System.Console.WriteLine("Enterキーで処理開始"); Console.ReadLine(); #region データのコピー // ワークシートの取得 // 1番目のシートを取得 ISheet readSheet = readBook.GetSheetAt(0); ISheet writeSheet = writeBook.GetSheetAt(0); // Excelデータ読み取り for (int i = 0; i < 10; i++) { data = new ExcelData(); // 行データ取得 IRow row = readSheet.GetRow(i); data.Name = row.GetCell(0).StringCellValue; // Numericはdouble型なのでintに変換した data.Age = (int)row.GetCell(1).NumericCellValue; data.TelNo = row.GetCell(2).StringCellValue; data.Address = row.GetCell(3).StringCellValue; dataList.Add(data); } // 読み取ったデータを書込先に書き込む for (int i = 0; i < dataList.Count; i++) { ICell cell = null; /* * 行(row)と列(cell)は取得できなかったら * 作成している。 * 空だったりすると「GetRow」「GetCell」で * nullが返ってくる場合があるから * 「??」は左の結果がnullなら右の結果を返す * 「null合体演算子」と呼ばれるもの */ IRow row = writeSheet.GetRow(i) ?? writeSheet.CreateRow(i); // 名前 cell = row.GetCell(0) ?? row.CreateCell(0); cell.SetCellValue(dataList[i].Name); // 年齢(intからdoubleに暗黙の型変換がされるが書いた) cell = row.GetCell(1) ?? row.CreateCell(1); cell.SetCellValue((double)dataList[i].Age); // 電話番号 cell = row.GetCell(2) ?? row.CreateCell(2); cell.SetCellValue(dataList[i].TelNo); // 住所 cell = row.GetCell(3) ?? row.CreateCell(3); cell.SetCellValue(dataList[i].Address); } // Excelを保存 using (fs = File.Create(writePath)) { writeBook.Write(fs); } #endregion } catch(Exception ex) { System.Console.WriteLine(ex.Message); } finally { System.Console.WriteLine("処理終了"); Console.ReadLine(); } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
namespace ExcelNNpoiSample { class ExcelData { // 名前 public string Name { get; set; } // 年齢 public int Age { get; set; } // 電話番号 public string TelNo { get; set; } // 住所 public string Address { get; set; } } } |
このサンプルは、1シート目の内容を、書き込み先の1シート目のセルに書き込んでいる。
書き込み先のセルにすでに値があれば、その値は読み込み元のセルの値で上書きされる。
注意点
行番号と列番号
「1列目、2列目」「1行目、2行目」と数えるExcelVBAなどと異なり、NPOIでは「0列目、1列目・・・」「0行目、1行目・・・」と数える。
0から数えていくので注意してもらいたい。
Excelの開き方
例えばExcelのブックを開くときに、FileStreamを使わずに、
1 |
writeBook = WorkbookFactory.Create(readPath); |
とすると、いつまでもファイルを掴んでいるため、ブックを保存する、
1 |
writeBook.Write(fs); |
で、「他のファイルが開いているために書き込みができない」というエラーになる。
このため、FileStreamを使用して、「ブックを読み込んだらすぐにそのファイルを閉じる」という処理に変更した。
また、一回ファイルが読み込めなくなると、冒頭の「WorkbookFactory.Create」でも同様のエラーが出始める。
ブックを読み込んだら、すぐにファイルを閉じる。ブックを書き込んだらすぐにファイルを閉じる。
ファイルを開きっぱなしにしないように気を付ける。
コメント
この記事へのトラックバックはありません。
CellやRowはそれぞれ
NPOI.SS.Util.CellUtil.GetCell();
NPOI.SS.Util.CellUtil.GetRow();
で取得すると、存在しない場合には作成して返してくれますよ。
コメント有難うございます。
返信が遅くなり申し訳ありません。
このような方法があるのですね。
アドバイスありがとうございます。
感謝です。
これからもよろしくお願いいたします。