Azure Functions 内で CSV を作成してファイルダウンロードさせる場合、中身がテキストなのでシンプルで扱いやすい反面、文字列の処理が漏れていたりするとカンマやダブルクォーテーションが混ざり込んでセルがズレてしまいます。そこで CSV をやめてエクセル形式でファイルが生成できれば CSV の課題が解消されるのではと考え、Azure Functions 内でエクセルを作成してファイルダウンロードできるか試してみました。
検証用 Azure Functions の作成
bash
func init mnrfapp --dotnet
cd mnrfapp
func new --name crxlsx --template HttpTrigger
dotnet add package DocumentFormat.OpenXml
エクセル作成コードに変更
crxlsx.cs
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
namespace mnrfapp
{
public static class crxlsx
{
[FunctionName("crxlsx")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
// メモリストリームを作成
var memoryStream = new MemoryStream();
// SpreadsheetDocument を作成
var spreadsheetDocument = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook);
// Workbook を作成
var workbookPart = spreadsheetDocument.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
// Worksheet を作成
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
// mySheet という名前を設定
Sheet sheet = new Sheet() {
Id = workbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = "mySheet"
};
sheets.Append(sheet);
// シートデータを取得
var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
// ヘッダ行を追加
var headerRow = new Row();
headerRow.Append(
new Cell() { CellValue = new CellValue("Hello"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("World"), DataType = CellValues.String }
);
sheetData.Append(headerRow);
// データ行を追加
var dataRow = new Row();
dataRow.Append(
new Cell() { CellValue = new CellValue("はろー"), DataType = CellValues.String },
new Cell() { CellValue = new CellValue("わーるど"), DataType = CellValues.String }
);
sheetData.Append(dataRow);
// SpreadsheetDocument を保存
workbookPart.Workbook.Save();
spreadsheetDocument.Dispose();
// メモリストリームをシークして先頭へ戻す
memoryStream.Seek(0, SeekOrigin.Begin);
// ファイルをダウンロードとして提供
return new FileContentResult(memoryStream.ToArray(), "application/octet-stream")
{
FileDownloadName = "sample.xlsx"
};
}
}
}
ダウンロードしたファイルを開いた結果
参考