static DateTime ExcelToSeedCore(IExcelData excelData, string file, FromOptions options, DateTime startTime, DateTime previousTime)
        {
            Log("  sheets");
            var fileName     = Path.GetFileName(file);
            var sheetsConfig = new SheetsConfig(options.only, options.ignore, options.subdivide, options.primary, options.mapping, options.alias);

            foreach (var sheetName in excelData.SheetNames)
            {
                var yamlTableName = sheetsConfig.YamlTableName(fileName, sheetName);
                if (yamlTableName == sheetName)
                {
                    Log($"    {yamlTableName}");
                }
                else
                {
                    Log($"    {yamlTableName} <- {sheetName}");
                }
                if (!sheetsConfig.IsUseSheet(fileName, sheetName, yamlTableName, OnOperation.From))
                {
                    Log("      ignore", "skip");
                    continue;
                }
                var subdivide = sheetsConfig.subdivide(fileName, yamlTableName, OnOperation.From);
                var seedTable = GetSeedTable(excelData, sheetName, options, subdivide);
                if (seedTable.Errors.Count != 0)
                {
                    continue;
                }
                new YamlData(
                    seedTable.ExcelToData(options.requireVersion),
                    subdivide.NeedSubdivide,
                    subdivide.CutPrefix,
                    subdivide.CutPostfix,
                    subdivide.SubdivideFilename,
                    options.format,
                    options.delete,
                    options.yamlColumns
                    ).WriteTo(
                    yamlTableName,
                    options.output,
                    options.seedExtension
                    );
                var now = DateTime.Now;
                DurationLog("      write-time", previousTime, now);
                previousTime = now;
            }
            return(previousTime);
        }
        static DateTime SeedToExcelCore(IExcelData excelData, string file, ToOptions options, DateTime startTime, DateTime previousTime)
        {
            Log("  sheets");
            var fileName      = Path.GetFileName(file);
            var sheetsConfig  = new SheetsConfig(options.only, options.ignore, null, null, options.mapping, options.alias);
            var yamlDataCache = new Dictionary <string, YamlData>(); // aliasのため同テーブルはキャッシュする

            foreach (var sheetName in excelData.SheetNames)
            {
                var yamlTableName = sheetsConfig.YamlTableName(fileName, sheetName);
                if (yamlTableName == sheetName)
                {
                    Log($"    {yamlTableName}");
                }
                else
                {
                    Log($"    {yamlTableName} -> {sheetName}");
                }
                if (!sheetsConfig.IsUseSheet(fileName, sheetName, yamlTableName, OnOperation.To))
                {
                    Log("      ignore", "skip");
                    continue;
                }
                var subdivide = sheetsConfig.subdivide(fileName, yamlTableName, OnOperation.To);
                var seedTable = GetSeedTable(excelData, sheetName, options, subdivide);
                if (seedTable.Errors.Count != 0)
                {
                    continue;
                }
                YamlData yamlData = null;
                if (!yamlDataCache.TryGetValue(yamlTableName, out yamlData))
                {
                    try {
                        yamlData = YamlData.ReadFrom(yamlTableName, options.seedInput, options.seedExtension, subdivide.KeyColumnName);
                        yamlDataCache[yamlTableName] = yamlData;
                    } catch (FileNotFoundException exception) {
                        Log("      skip", $"seed file [{exception.FileName}] not found");
                        continue;
                    }
                }
                try {
                    seedTable.DataToExcel(yamlData.Data, options.delete);
                } catch (IdParseException exception) {
                    WriteInfo($"      ERROR: {exception.Message}");
                    throw new CannotContinueException();
                }
                var now = DateTime.Now;
                DurationLog("      write-time", previousTime, now);
                previousTime = now;
            }
            // 数式を再計算して結果をキャッシュする
            if (options.calcFormulas && excelData is EPPlus.ExcelData)
            {
                ((EPPlus.ExcelData)excelData).Calculate();
            }
            if (options.output.Length == 0)
            {
                excelData.Save();
                Log("  write-path", "overwrite");
            }
            else
            {
                var writePath = Path.Combine(options.output, file);
                Log("  write-path", writePath);
                if (!Directory.Exists(options.output))
                {
                    Directory.CreateDirectory(options.output);
                }
                excelData.SaveAs(writePath);
            }
            var end = DateTime.Now;

            DurationLog("  write-time", previousTime, end);
            return(end);
        }