Magicodes.IE Excel複数シートインポート実装ガイド

Magicodes.IE.Excel を用いた複数シートを含む Excel ファイルのインポート機能について説明します。このライブラリは、データ構造が同じまたは異なる複数シートを効率的に取り込むことを可能にします。

構造が同一の複数シートのインポート

1. 単一シート用の DTO 定義

以下は、学生情報を格納する基本 DTO の定義例です。

[ExcelImporter(IsLabelingError = true)]
public class StudentImportModel
{
    [ImporterHeader(Name = "通番")]
    public int Sequence { get; set; }

    [ImporterHeader(Name = "学籍番号", IsAllowRepeat = false)]
    [MaxLength(30, ErrorMessage = "学籍番号は30文字以内で入力してください")]
    [Required(ErrorMessage = "学籍番号は必須です")]
    public string StudentId { get; set; }

    [ImporterHeader(Name = "氏名")]
    [MaxLength(50, ErrorMessage = "氏名は50文字以内で入力してください")]
    [Required(ErrorMessage = "氏名は必須です")]
    public string FullName { get; set; }

    [ImporterHeader(Name = "身份证番号", IsAllowRepeat = false)]
    [MaxLength(18, ErrorMessage = "身份证番号は18桁で入力してください")]
    [Required(ErrorMessage = "身份证番号は必須です")]
    public string IdentityCard { get; set; }

    [ImporterHeader(Name = "性別")]
    [Required(ErrorMessage = "性別は必須です")]
    [ValueMapping("男性", 0)]
    [ValueMapping("女性", 1)]
    public GenderType Gender { get; set; }

    [ImporterHeader(Name = "住所")]
    [MaxLength(200, ErrorMessage = "住所は200文字以内で入力してください")]
    [Required(ErrorMessage = "住所は必須です")]
    public string Address { get; set; }

    [ImporterHeader(Name = "保護者氏名")]
    [MaxLength(50, ErrorMessage = "保護者氏名は50文字以内で入力してください")]
    [Required(ErrorMessage = "保護者氏名は必須です")]
    public string GuardianName { get; set; }

    [ImporterHeader(Name = "保護者電話番号")]
    [MaxLength(20, ErrorMessage = "保護者電話番号は20文字以内で入力してください")]
    public string GuardianPhoneNo { get; set; }

    [ImporterHeader(Name = "学籍番号(内部)")]
    [MaxLength(30, ErrorMessage = "学籍番号(内部)は30文字以内で入力してください")]
    public string InternalStudentId { get; set; }

    [ImporterHeader(Name = "寮番号")]
    [MaxLength(20, ErrorMessage = "寮番号は20文字以内で入力してください")]
    public string DormNumber { get; set; }

    [ImporterHeader(Name = "QQ番号")]
    [MaxLength(30, ErrorMessage = "QQ番号は30文字以内で入力してください")]
    public string QqAccount { get; set; }

    [ImporterHeader(Name = "民族")]
    [MaxLength(2, ErrorMessage = "民族は2文字以内で入力してください")]
    public string EthnicGroup { get; set; }

    [ImporterHeader(Name = "戸籍区分")]
    [MaxLength(10, ErrorMessage = "戸籍区分は10文字以内で入力してください")]
    public string HouseholdCategory { get; set; }

    [ImporterHeader(Name = "個人電話番号")]
    [MaxLength(20, ErrorMessage = "個人電話番号は20文字以内で入力してください")]
    public string PersonalPhoneNo { get; set; }

    [ImporterHeader(Name = "状態")]
    public StudentState? Status { get; set; }

    [ImporterHeader(Name = "備考")]
    [MaxLength(200, ErrorMessage = "備考は200文字以内で入力してください")]
    public string Notes { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public bool? IsBoarding { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public Guid ClassId { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public Guid? SchoolId { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public Guid? CampusId { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public Guid? MajorId { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public Guid? GradeId { get; set; }
}

2. 複数シートをまとめて取り込むための親 DTO

各シートに対応するプロパティを定義し、ExcelImporter 属性で対象シート名を指定します。

public class MultiClassImportModel
{
    [ExcelImporter(SheetName = "1組_データ")]
    public StudentImportModel ClassOneStudents { get; set; }

    [ExcelImporter(SheetName = "2組_データ")]
    public StudentImportModel ClassTwoStudents { get; set; }
}

注意:この親 DTO 自体には ExcelImporter アトリビュートは不要です。

3. Excel ファイルの構成要件

  • 各シートは同一の構造(ヘッダー行・列位置)を持つこと
  • 各シートの列名は ImporterHeaderName 属性と一致すること

4. インポート処理コード

var importer = new ExcelImporter();

var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Templates", "複数学級_学生情報.xlsx");

// 各シートごとに結果が Dictionary として返される(Key: シート名、Value: ImportResult)
var resultDictionary = await importer.ImportSameSheets<MultiClassImportModel, StudentImportModel>(filePath);

foreach (var entry in resultDictionary)
{
    var sheetName = entry.Key;
    var importResult = entry.Value;

    if (!importResult.IsValid)
    {
        // エラーハンドリング
        var errors = importResult.ValidationResults;
    }

    var students = importResult.Data.ToList();
    // 各シートのデータを処理する
}

構造が異なる複数シートのインポート

1. 複数の DTO を定義

以下では、学生情報とは別に支払い履歴の構造を持つ DTO を定義しています。

[ExcelImporter(IsLabelingError = true)]
public class PaymentLogImportModel
{
    [ImporterHeader(Name = "生徒名")]
    [MaxLength(30, ErrorMessage = "生徒名は30文字以内で入力してください")]
    [Required(ErrorMessage = "生徒名は必須です")]
    public string StudentName { get; set; }

    [ImporterHeader(Name = "身份证番号")]
    [MaxLength(18, ErrorMessage = "身份证番号は18桁で入力してください")]
    [MinLength(18, ErrorMessage = "身份证番号は18桁である必要があります")]
    [Required(ErrorMessage = "身份证番号は必須です")]
    public string IdentityCardNumber { get; set; }

    [ImporterHeader(Name = "支払タイプ")]
    [Required(ErrorMessage = "支払タイプは必須です")]
    public string PaymentType { get; set; }

    [ImporterHeader(Name = "金額")]
    [Range(0.01, 1000000, ErrorMessage = "金額は0.01~1,000,000の範囲で入力してください")]
    [Required(ErrorMessage = "金額は必須です")]
    public decimal Amount { get; set; }

    [ImporterHeader(Name = "支払日")]
    [MaxLength(8, ErrorMessage = "支払日は8文字以内で入力してください")]
    [RegularExpression(@"\d{6,8}", ErrorMessage = "支払日は YYYYMM または YYYYMMDD 形式で入力してください")]
    public string PaymentDate { get; set; }

    [ImporterHeader(Name = "領収票番号")]
    [MaxLength(200, ErrorMessage = "領収票番号は200文字以内で入力してください")]
    public string ReceiptNumbers { get; set; }

    [ImporterHeader(Name = "備考")]
    [MaxLength(500, ErrorMessage = "備考は500文字以内で入力してください")]
    public string Comments { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public DateTime? CreatedAt { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public int? ChargeProjectId { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public Guid? ClassId { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public string ClassName { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public Guid? GradeId { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public string GradeName { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public Guid? MajorId { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public string MajorName { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public Guid? CampusId { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public string CampusName { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public Guid? SchoolId { get; set; }

    [ImporterHeader(IsIgnore = true)]
    public string SchoolName { get; set; }
}

2. 異なるシートに対応する親 DTO

public class MixedImportModel
{
    [ExcelImporter(SheetName = "学生一覧")]
    public StudentImportModel StudentList { get; set; }

    [ExcelImporter(SheetName = "支払い履歴")]
    public PaymentLogImportModel PaymentRecords { get; set; }
}

3. Excel ファイルの構成要件

  • シート名は絶対に一致させる必要があります(大文字・小文字を区別しない)
  • 各シートの構造はそれぞれ対応する DTO と一致している必要があります

4. インポート処理コード

var importer = new ExcelImporter();

var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Templates", "混合データ.xlsx");

// ImportDifferentSheets メソッドは、各シートが独自の DTO にマッピングされるケースで使用
var combinedResult = await importer.ImportDifferentSheets<MixedImportModel>(filePath);

// 各シートに対応する結果を持つ
var studentImport = combinedResult.StudentList;
var paymentImport = combinedResult.PaymentRecords;

if (studentImport.IsValid)
{
    var students = studentImport.Data.ToList();
    // 学生データ処理
}

if (paymentImport.IsValid)
{
    var payments = paymentImport.Data.ToList();
    // 支払いデータ処理
}

タグ: Magicodes.IE Excel ASP.NET Core データインポート 複数シート

7月1日 22:59 投稿