Properties { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/seedtable-egui/Data/PersonalFormValues.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace seedtable_egui.Data {
7 | public class PersonalFormValues {
8 | public string DataExcelsDirectoryPath { get; set; }
9 | public string TemplateExcelsDirectoryPath { get; set; }
10 |
11 | public PersonalFormValues() { }
12 | public PersonalFormValues(string dataExcelsDirectoryPath, string templateExcelsDirectoryPath) {
13 | DataExcelsDirectoryPath = dataExcelsDirectoryPath;
14 | TemplateExcelsDirectoryPath = templateExcelsDirectoryPath;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/seedtable-gui/PersonalFormValues.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace seedtable_gui {
8 | public class PersonalFormValues {
9 | public string DataExcelsDirectoryPath { get; set; }
10 | public string TemplateExcelsDirectoryPath { get; set; }
11 |
12 | public PersonalFormValues() { }
13 | public PersonalFormValues(string dataExcelsDirectoryPath, string templateExcelsDirectoryPath) {
14 | DataExcelsDirectoryPath = dataExcelsDirectoryPath;
15 | TemplateExcelsDirectoryPath = templateExcelsDirectoryPath;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/seedtable-egui/Data/FormValues.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace seedtable_egui.Data {
7 | public class FormValues {
8 | public string SeedPath { get; set; }
9 | public string SettingPath { get; set; }
10 | public string SourcePath { get; set; } // FormValuesX11 で作られた設定との互換
11 | public string YamlToExcelTargetFolder { get; set; } // FormValuesX11 で作られた設定との互換
12 |
13 | public FormValues() { }
14 | public FormValues(string seedPath, string settingPath) {
15 | SeedPath = seedPath;
16 | SettingPath = settingPath;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/seedtable-gui/FormValues.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace seedtable_gui {
8 | public class FormValues {
9 | public string SeedPath { get; set; }
10 | public string SettingPath { get; set; }
11 | public string SourcePath { get; set; } // FormValuesX11 で作られた設定との互換
12 | public string YamlToExcelTargetFolder { get; set; } // FormValuesX11 で作られた設定との互換
13 |
14 | public FormValues() { }
15 | public FormValues(string seedPath, string settingPath) {
16 | SeedPath = seedPath;
17 | SettingPath = settingPath;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/seedtable-egui/wwwroot/css/site.css:
--------------------------------------------------------------------------------
1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
2 |
3 | html, body {
4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
5 | width: 100%;
6 | height: 100%;
7 | margin: 0;
8 | padding: 0;
9 | }
10 |
11 | #blazor-error-ui {
12 | background: lightyellow;
13 | bottom: 0;
14 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
15 | display: none;
16 | left: 0;
17 | padding: 0.6rem 1.25rem 0.7rem 1.25rem;
18 | position: fixed;
19 | width: 100%;
20 | z-index: 1000;
21 | }
22 |
23 | #blazor-error-ui .dismiss {
24 | cursor: pointer;
25 | position: absolute;
26 | right: 0.75rem;
27 | top: 0.5rem;
28 | }
29 |
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/Program.cs:
--------------------------------------------------------------------------------
1 | namespace XmSeedtable
2 | {
3 | class Program
4 | {
5 | static void Main(string[] args) {
6 | //System.Diagnostics.Debug.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(System.Console.Out));
7 | TonNurako.Application.RegisterGlobals();
8 | var app = new TonNurako.ApplicationContext();
9 | app.Name = "SeedTable";
10 | app.FallbackResource.Add("*fontList", "-misc-fixed-medium-r-normal--14-*-*-*-*-*-*-*:");
11 | app.FallbackResource.Add("*geometry", "+100+100");
12 | app.FallbackResource.Add("*title", "SeedTable");
13 |
14 | TonNurako.Application.Run(app, new SeedTableX11());
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/seedtable-egui/Pages/Error.razor:
--------------------------------------------------------------------------------
1 | @page "/error"
2 |
3 |
4 | Error.
5 | An error occurred while processing your request.
6 |
7 | Development Mode
8 |
9 | Swapping to Development environment will display more detailed information about the error that occurred.
10 |
11 |
12 | The Development environment shouldn't be enabled for deployed applications.
13 | It can result in displaying sensitive information from exceptions to end users.
14 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development
15 | and restarting the app.
16 |
--------------------------------------------------------------------------------
/seedtable/Properties/PublishProfiles/osx-x64.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | FileSystem
8 | Release
9 | Any CPU
10 | netcoreapp3.1
11 | bin\Release\netcoreapp3.1\publish\osx-x64
12 | osx-x64
13 | true
14 | True
15 | False
16 | False
17 |
18 |
--------------------------------------------------------------------------------
/seedtable/Properties/PublishProfiles/win-x86.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | FileSystem
8 | Release
9 | Any CPU
10 | netcoreapp3.1
11 | bin\Release\netcoreapp3.1\publish\win-x86
12 | win-x86
13 | true
14 | True
15 | True
16 | False
17 |
18 |
--------------------------------------------------------------------------------
/seedtable-gui/Properties/PublishProfiles/win-x86.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | FileSystem
8 | Release
9 | Any CPU
10 | netcoreapp3.1
11 | bin\Release\netcoreapp3.1\publish\win-x86
12 | win-x86
13 | true
14 | True
15 | True
16 | False
17 |
18 |
--------------------------------------------------------------------------------
/seedtable/Properties/PublishProfiles/linux-x64.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | FileSystem
8 | Release
9 | Any CPU
10 | netcoreapp3.1
11 | bin\Release\netcoreapp3.1\publish\linux-x64
12 | linux-x64
13 | true
14 | True
15 | False
16 | False
17 |
18 |
--------------------------------------------------------------------------------
/seedtable-test/test-resources/commands.sh:
--------------------------------------------------------------------------------
1 | ../../seedtable/bin/Debug/seedtable.exe from seedtable_example.xlsx -o seeds --yaml-columns data_yaml -e EPPlus
2 | ../../seedtable/bin/Debug/seedtable.exe to seedtable_example.xlsx -s seeds_to -o seeds_to_union --yaml-columns data_yaml -e EPPlus --calc-formulas
3 | ../../seedtable/bin/Debug/seedtable.exe from seedtable_example.xlsx -i seeds_to_union -o seeds_to_union --yaml-columns data_yaml -e EPPlus
4 | ../../seedtable/bin/Debug/seedtable.exe to seedtable_example.xlsx -s seeds_to -o seeds_to_delete --yaml-columns data_yaml -e EPPlus --delete --calc-formulas
5 | ../../seedtable/bin/Debug/seedtable.exe from seedtable_example.xlsx -i seeds_to_delete -o seeds_to_delete --yaml-columns data_yaml -e EPPlus
6 | rm ./seeds_to_union/seedtable_example.xlsx
7 | rm ./seeds_to_delete/seedtable_example.xlsx
8 |
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/FormValuesX11.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace XmSeedtable {
8 | public class FormValuesX11 {
9 | public string SeedPath { get; set; }
10 | public string SettingPath { get; set; }
11 | public string SourcePath { get; set; }
12 | public string YamlToExcelTargetFolder { get; set; }
13 |
14 | public FormValuesX11() { }
15 | public FormValuesX11(string seedPath, string settingPath, string sourcePath, string yamlToExcelTargetFolder) {
16 | SeedPath = seedPath;
17 | SettingPath = settingPath;
18 | SourcePath = sourcePath;
19 | YamlToExcelTargetFolder = yamlToExcelTargetFolder;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/Properties/PublishProfiles/osx-x64.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | FileSystem
8 | Release
9 | Any CPU
10 | netcoreapp3.1
11 | bin\Release\netcoreapp3.1\publish\osx-x64\XmSeedtable
12 | osx-x64
13 | true
14 | False
15 | False
16 | False
17 |
18 |
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/Properties/PublishProfiles/linux-x64.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | FileSystem
8 | Release
9 | Any CPU
10 | netcoreapp3.1
11 | bin\Release\netcoreapp3.1\publish\linux-x64\XmSeedtable
12 | linux-x64
13 | true
14 | False
15 | False
16 | False
17 |
18 |
--------------------------------------------------------------------------------
/releases.ps1:
--------------------------------------------------------------------------------
1 | New-Item -Force -ItemType Directory releases
2 | Compress-Archive -Force -Path ./seedtable/bin/Release/netcoreapp3.1/publish/win-x86/seedtable.exe -DestinationPath releases/seedtable.zip
3 | Compress-Archive -Force -Path ./seedtable/bin/Release/netcoreapp3.1/publish/linux-x64/seedtable -DestinationPath releases/seedtable-linux.zip
4 | Compress-Archive -Force -Path ./seedtable/bin/Release/netcoreapp3.1/publish/osx-x64/seedtable -DestinationPath releases/seedtable-osx.zip
5 | Compress-Archive -Force -Path ./seedtable/bin/Release/netcoreapp3.1/publish/portable -DestinationPath releases/seedtable-need-runtime.zip
6 | Compress-Archive -Force -Path ./seedtable-gui/bin/Release/netcoreapp3.1/publish/win-x86/seedtable-gui.exe -DestinationPath releases/seedtable-gui.zip
7 | Compress-Archive -Force -Path ./seedtable-gui/bin/Release/netcoreapp3.1/publish/portable -DestinationPath releases/seedtable-gui-need-runtime.zip
8 |
--------------------------------------------------------------------------------
/seedtable-egui/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Hosting;
10 | using Microsoft.Extensions.Logging;
11 | using ElectronNET.API;
12 |
13 | namespace seedtable_egui {
14 | public class Program {
15 | public static void Main(string[] args) {
16 | CreateHostBuilder(args).Build().Run();
17 | }
18 |
19 | public static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder => {
22 | webBuilder.UseElectron(args);
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/seedtable-egui/Data/Electron/JSRuntimeExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.JSInterop;
6 |
7 | namespace seedtable_egui.Data.Electron {
8 | public static class JSRuntimeExtensions {
9 | public static ValueTask ShowOpenDialog(this IJSRuntime js, OpenDialogOption option) {
10 | return js.InvokeAsync("showOpenDialog", option);
11 | }
12 |
13 | public static ValueTask ShowSaveDialog(this IJSRuntime js, SaveDialogOption option) {
14 | return js.InvokeAsync("showSaveDialog", option);
15 | }
16 |
17 | public static ValueTask ShowErrorBox(this IJSRuntime js, string content = null, string title = "エラー") {
18 | return js.InvokeVoidAsync("showErrorBox", title, content);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/seedtable-egui/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:60474",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "Electron.NET App": {
12 | "commandName": "Executable",
13 | "executablePath": "electronize",
14 | "commandLineArgs": "start",
15 | "workingDirectory": "."
16 | },
17 |
18 | "IIS Express": {
19 | "commandName": "IISExpress",
20 | "launchBrowser": true,
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | }
24 | },
25 | "seedtable-egui": {
26 | "commandName": "Project",
27 | "launchBrowser": true,
28 | "applicationUrl": "http://localhost:5000",
29 | "environmentVariables": {
30 | "ASPNETCORE_ENVIRONMENT": "Development"
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/seedtable-x11/gulpfile.js:
--------------------------------------------------------------------------------
1 | const k = require('gulp');
2 | const msbuild = require("gulp-msbuild");
3 | const shell = require('gulp-shell');
4 | const LPTSTR = require('run-sequence');
5 | const minimist = require("minimist");
6 |
7 | const TNK_BASE = "./TonNurako"
8 |
9 | var env = minimist(process.argv.slice(2));
10 | var kOnfiguration = 'Debug';
11 | if (env.release) {
12 | kOnfiguration = 'Release';
13 | }
14 |
15 | function ccsf(format) {
16 | return `${TNK_BASE}/${format}`;
17 | }
18 |
19 | k.task('build:local', () =>{
20 | return k.src("XmSeedtable.sln")
21 | .pipe(msbuild({
22 | stdout: true,
23 | errorOnFail: true,
24 | configuration: kOnfiguration
25 | }));
26 | });
27 |
28 | k.task('build', ['build:TonNurako']);
29 |
30 | k.task('_watch', () => {
31 | k.watch(
32 | [ccsf('XmSeedtable/**/*.cs')], ['build:local'])
33 | });
34 |
35 | k.task('watch', (dome) => {
36 | return LPTSTR('build:local', '_watch',dome);
37 | }
38 | );
39 | k.task('default', ['build:local']);
40 |
--------------------------------------------------------------------------------
/seedtable-test/FromTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class FromTest : FromToTestBase {
13 | [Fact]
14 | public void EqualToExample() {
15 | var options = BuildFromOptions();
16 | Prepare(options);
17 |
18 | foreach (var sourcePath in Directory.GetFiles(Paths.SourceSeedPath)) {
19 | var filename = Path.GetFileName(sourcePath);
20 | var destinationPath = Path.Combine(options.output, filename);
21 | Assert.True(File.Exists(destinationPath));
22 | var sourceContent = GetYamlData(sourcePath);
23 | var destinationContent = GetYamlData(destinationPath);
24 | Assert.Equal(sourceContent, destinationContent);
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/seedtable-gui/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // このコードはツールによって生成されました。
4 | // ランタイム バージョン:4.0.30319.42000
5 | //
6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
7 | // コードが再生成されるときに損失したりします。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace seedtable_gui.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/seedtable-egui/electron.manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "executable": "seedtable-egui",
3 | "splashscreen": {
4 | "imageFile": ""
5 | },
6 | "singleInstance": true,
7 | "build": {
8 | "appId": "net.narazaka.seedtable-egui.app",
9 | "productName": "seedtable-egui",
10 | "copyright": "Copyright © 2019 Narazaka",
11 | "buildVersion": "4.0.0",
12 | "compression": "maximum",
13 | "directories": {
14 | "output": "../../../bin/Desktop"
15 | },
16 | "extraResources": [
17 | {
18 | "from": "./bin",
19 | "to": "bin",
20 | "filter": ["**/*"]
21 | }
22 | ],
23 | "files": [
24 | {
25 | "from": "./ElectronHostHook/node_modules",
26 | "to": "ElectronHostHook/node_modules",
27 | "filter": ["**/*"]
28 | },
29 | "**/*"
30 | ],
31 | "win": {
32 | "target": "dir",
33 | "icon": "../../../seedtable-gui.ico"
34 | },
35 | "linux": {
36 | "target": "dir",
37 | "icon": "../../../seedtable-gui.png"
38 | },
39 | "mac": {
40 | "target": "dir",
41 | "icon": "../../../seedtable-gui-osx.png"
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/seedtable/SheetNameMaps.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace SeedTable {
5 | public class SheetNameMaps : List {
6 | public static SheetNameMaps FromMixed(IEnumerable mixedNames = null) {
7 | return
8 | mixedNames == null ?
9 | new SheetNameMaps() :
10 | new SheetNameMaps(mixedNames.Select(mixedName => SheetNameMap.FromMixed(mixedName)));
11 | }
12 |
13 | public SheetNameMaps() : base() { }
14 |
15 | public SheetNameMaps(IEnumerable sheetNameMaps) : base(
16 | sheetNameMaps.OrderByDescending(sheetNameMap => (int)sheetNameMap.FileName.MatchType) // ワイルドカードの判定優先順位を低くする
17 | ) { }
18 |
19 | // file/sheet指定が存在して完全マッチ、あるいは指定が存在しない場合true
20 | public SheetNameMap Find(string fileName, string sheetName) {
21 | return Find(sheetNameMap => sheetNameMap.IsMatch(fileName, sheetName));
22 | }
23 |
24 | public bool Contains(string fileName, string sheetName) {
25 | return Find(fileName, sheetName) != null;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/seedtable/SheetNameOnFileNames.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace SeedTable {
5 | class SheetNameOnFileNames : List {
6 | public static SheetNameOnFileNames FromMixed(IEnumerable mixedNames = null) {
7 | return
8 | mixedNames == null ?
9 | new SheetNameOnFileNames() :
10 | new SheetNameOnFileNames(mixedNames.Select(mixedName => SheetNameOnFileName.FromMixed(mixedName)));
11 | }
12 |
13 | public SheetNameOnFileNames() : base() { }
14 |
15 | public SheetNameOnFileNames(IEnumerable sheetNameOnFileName) : base(sheetNameOnFileName) { }
16 |
17 | // file/sheet指定が存在して完全マッチ、あるいは指定が存在しない場合true
18 | public bool IsUseSheet(string fileName, string sheetName) {
19 | var sheetNameOnFileName = this.FirstOrDefault(_sheetNameOnFileName => _sheetNameOnFileName.SheetName.IsMatch(sheetName));
20 | if (sheetNameOnFileName == null) return true; // 指定がない
21 | if (sheetNameOnFileName.FileName.IsMatch(fileName)) return true; // 完全マッチ
22 | return false;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/seedtable-test/test-resources/seeds/foos.yml:
--------------------------------------------------------------------------------
1 | data1:
2 | id: 1
3 | value: 100
4 | data2:
5 | id: 2
6 | value: 200
7 | data3:
8 | id: 3
9 | value: 300
10 | data4:
11 | id: 4
12 | value: 400
13 | data5:
14 | id: 5
15 | value: 500
16 | data6:
17 | id: 6
18 | value: 600
19 | data7:
20 | id: 7
21 | value: 700
22 | data8:
23 | id: 8
24 | value: 800
25 | data9:
26 | id: 9
27 | value: 900
28 | data10:
29 | id: 10
30 | value: 1000
31 | data11:
32 | id: 11
33 | value: 1100
34 | data12:
35 | id: 12
36 | value: 1200
37 | data13:
38 | id: 13
39 | value: 1300
40 | data14:
41 | id: 14
42 | value: 1400
43 | data15:
44 | id: 15
45 | value: 1500
46 | data16:
47 | id: 16
48 | value: 1600
49 | data17:
50 | id: 17
51 | value: 1700
52 | data18:
53 | id: 18
54 | value: 1800
55 | data19:
56 | id: 19
57 | value: 1900
58 | data20:
59 | id: 20
60 | value: 2000
61 | data21:
62 | id: 21
63 | value: 2100
64 | data22:
65 | id: 22
66 | value: 2200
67 | data23:
68 | id: 23
69 | value: 2300
70 | data24:
71 | id: 24
72 | value: 2400
73 | data25:
74 | id: 25
75 | value: 2500
76 | data26:
77 | id: 26
78 | value: 2600
79 |
--------------------------------------------------------------------------------
/seedtable-test/test-resources/seeds_to_union/foos.yml:
--------------------------------------------------------------------------------
1 | data1:
2 | id: 1
3 | value: 100
4 | data2:
5 | id: 2
6 | value: 200
7 | data3:
8 | id: 3
9 | value: 300
10 | data4:
11 | id: 4
12 | value: 400
13 | data5:
14 | id: 5
15 | value: 500
16 | data6:
17 | id: 6
18 | value: 600
19 | data7:
20 | id: 7
21 | value: 700
22 | data8:
23 | id: 8
24 | value: 800
25 | data9:
26 | id: 9
27 | value: 900
28 | data10:
29 | id: 10
30 | value: 1000
31 | data11:
32 | id: 11
33 | value: 1100
34 | data12:
35 | id: 12
36 | value: 1200
37 | data13:
38 | id: 13
39 | value: 1300
40 | data14:
41 | id: 14
42 | value: 1400
43 | data15:
44 | id: 15
45 | value: 1500
46 | data16:
47 | id: 16
48 | value: 1600
49 | data17:
50 | id: 17
51 | value: 1700
52 | data18:
53 | id: 18
54 | value: 1800
55 | data19:
56 | id: 19
57 | value: 1900
58 | data20:
59 | id: 20
60 | value: 2000
61 | data21:
62 | id: 21
63 | value: 2100
64 | data22:
65 | id: 22
66 | value: 2200
67 | data23:
68 | id: 23
69 | value: 2300
70 | data24:
71 | id: 24
72 | value: 2400
73 | data25:
74 | id: 25
75 | value: 2500
76 | data26:
77 | id: 26
78 | value: 2600
79 | data100:
80 | id: 100
81 | value: 10000
82 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: "{build}"
2 | image: Visual Studio 2019
3 | branches:
4 | except:
5 | - gh-pages
6 | platform:
7 | - Any CPU
8 | configuration:
9 | - Release
10 | before_build:
11 | - ps: Install-Product node LTS
12 | - dotnet restore
13 | - dotnet tool install ElectronNET.CLI -g --version 8.31.1
14 | - npm install -g electron-builder
15 | build_script:
16 | - .\publish.bat
17 | - ps: .\releases.ps1
18 | - .\publish-egui.bat
19 | - ps: .\releases-egui.ps1
20 | test_script:
21 | - dotnet test
22 | artifacts:
23 | - path: releases/seedtable.zip
24 | name: seedtable
25 | - path: releases/seedtable-linux.zip
26 | name: seedtable-linux
27 | - path: releases/seedtable-osx.zip
28 | name: seedtable-osx
29 | - path: releases/seedtable-need-runtime.zip
30 | name: seedtable-need-runtime
31 | - path: releases/seedtable-gui.zip
32 | name: seedtable-gui
33 | - path: releases/seedtable-gui-need-runtime.zip
34 | name: seedtable-gui-need-runtime
35 | - path: releases/seedtable-egui-win.zip
36 | name: seedtable-egui-win
37 | deploy:
38 | provider: GitHub
39 | auth_token:
40 | secure: pXNt94D78LGVsrWyPtoaFzXZI1rUt8iCaEvjjhQnM1hwyH/eV1Vnh/WhJQ9eLmgR
41 | draft: false
42 | prerelease: false
43 | artifact: /releases\/seedtable.*\.zip/
44 | on:
45 | appveyor_repo_tag: true
46 |
--------------------------------------------------------------------------------
/seedtable-test/PrimaryTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class PrimaryTest : FromToTestBase {
13 | private const string SheetName = "foos";
14 |
15 | [Theory]
16 | [InlineData("seedtable_example.xlsx")]
17 | [InlineData("seedtable_example_other.xlsx")]
18 | private void WithFileNameOnly(string fileName) {
19 | var options = BuildFromOptions(new string[] { "seedtable_example.xlsx", "seedtable_example_other.xlsx" });
20 | options.primary = new string[] { $"{fileName}/{SheetName}" };
21 | Prepare(options);
22 |
23 | var sourcePath = Path.Combine(fileName == "seedtable_example.xlsx" ? Paths.SourceSeedPath : Paths.OtherSeedPath, $"{SheetName}.yml");
24 | var destinationPath = Path.Combine(options.output, $"{SheetName}.yml");
25 | Assert.True(File.Exists(destinationPath));
26 | var sourceContent = GetYamlData(sourcePath);
27 | var destinationContent = GetYamlData(destinationPath);
28 | Assert.Equal(sourceContent, destinationContent);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/seedtable-test/Paths.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace seedtable_test {
4 | public static class Paths {
5 | public static readonly string SourceExcelName = "seedtable_example.xlsx";
6 | public static readonly string TestResourcesPath = Path.Combine("../../../test-resources");
7 | public static readonly string SourceExcelPath = Path.Combine(TestResourcesPath, SourceExcelName);
8 | public static readonly string SourceSeedPath = Path.Combine(TestResourcesPath, "seeds");
9 | public static readonly string ToSeedPath = Path.Combine(TestResourcesPath, "seeds_to");
10 | public static readonly string ToUnionSeedPath = Path.Combine(TestResourcesPath, "seeds_to_union");
11 | public static readonly string ToDeleteSeedPath = Path.Combine(TestResourcesPath, "seeds_to_delete");
12 | public static readonly string OtherSeedPath = Path.Combine(TestResourcesPath, "seeds_other");
13 | public static readonly string AliasSeedPath = Path.Combine(TestResourcesPath, "seeds_alias");
14 | public static readonly string DestinationBasePath = Path.Combine("../../../test-tmp");
15 | public static string DestinationSeedPath(string seedPath = null) {
16 | return Path.Combine(DestinationBasePath, seedPath ?? Path.GetRandomFileName());
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/seedtable-egui/seedtable-egui.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp3.1
4 | seedtable_egui
5 | Narazaka
6 | 4.0.1
7 | seedtable
8 | MIT
9 | https://github.com/seed-ui/seedtable
10 | https://github.com/seed-ui/seedtable.git
11 | seedtable-gui.ico
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | PreserveNewest
30 |
31 |
32 |
--------------------------------------------------------------------------------
/seedtable-test/SheetNameWithFileNameTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class SheetNameWithFileNameTest : FromToTestBase {
13 | private const string SheetName = "foos";
14 |
15 | [Theory]
16 | [InlineData("seedtable_example.xlsx")]
17 | [InlineData("seedtable_example_other.xlsx")]
18 | private void WithFileNameOnly(string fileName) {
19 | var options = BuildFromOptions(new string[] { "seedtable_example.xlsx", "seedtable_example_other.xlsx" });
20 | options.only = new string[] { $"{fileName}/{SheetName}" };
21 | Prepare(options);
22 |
23 | var sourcePath = Path.Combine(fileName == "seedtable_example.xlsx" ? Paths.SourceSeedPath : Paths.OtherSeedPath, $"{SheetName}.yml");
24 | var destinationPath = Path.Combine(options.output, $"{SheetName}.yml");
25 | Assert.True(File.Exists(destinationPath));
26 | var sourceContent = GetYamlData(sourcePath);
27 | var destinationContent = GetYamlData(destinationPath);
28 | Assert.Equal(sourceContent, destinationContent);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/seedtable/SheetNameMap.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace SeedTable {
5 | public class SheetNameMap {
6 | public static SheetNameMap FromMixed(string mixedName) {
7 | var result = Regex.Match(mixedName, @"^([^:/]+):(?:([^:/]+)/)?([^:/]+)$");
8 | if (!result.Success) throw new Exception($"{mixedName} is wrong mapping rule definition");
9 | var yamlTableName = result.Groups[1].Value;
10 | var fileName = result.Groups[2].Value;
11 | if (fileName.Length == 0) fileName = "*";
12 | var sheetName = result.Groups[3].Value;
13 | return new SheetNameMap(yamlTableName, fileName, sheetName);
14 | }
15 |
16 | public string YamlTableName { get; }
17 | public Wildcard FileName { get; } = null;
18 | public string SheetName { get; }
19 |
20 | public SheetNameMap(
21 | string yamlTableName,
22 | string fileName,
23 | string sheetName
24 | ) {
25 | YamlTableName = yamlTableName;
26 | FileName = new Wildcard(fileName);
27 | SheetName = sheetName;
28 | }
29 |
30 | public bool IsMatch(string fileName, string sheetName) {
31 | return FileName.IsMatch(fileName) && SheetName == sheetName;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/seedtable/SheetNameWithSubdivides.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace SeedTable {
5 | class SheetNameWithSubdivides : List {
6 | public static SheetNameWithSubdivides FromMixed(IEnumerable mixedNames = null) {
7 | return mixedNames == null ?
8 | new SheetNameWithSubdivides() :
9 | new SheetNameWithSubdivides(
10 | mixedNames.Select(mixedName => SheetNameWithSubdivide.FromMixed(mixedName))
11 | );
12 | }
13 |
14 | public SheetNameWithSubdivides() : base() { }
15 |
16 | public SheetNameWithSubdivides(IEnumerable sheetNameWithSubdivides) : base(
17 | sheetNameWithSubdivides.OrderBy(
18 | sheetNameWithSubdivide =>
19 | - (int)sheetNameWithSubdivide.FileName.MatchType - 10 * (int)sheetNameWithSubdivide.SheetName.MatchType
20 | )
21 | ) { }
22 |
23 | public SheetNameWithSubdivide Find(string fileName, string sheetName, OnOperation onOperation) {
24 | return Find(sheetNameWithSubdivide => sheetNameWithSubdivide.IsMatch(fileName, sheetName, onOperation));
25 | }
26 |
27 | public bool Contains(string fileName, string sheetName, OnOperation onOperation) {
28 | return Find(fileName, sheetName, onOperation) != null;
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/YamlToExcelDialogX11.Sinatra.cs:
--------------------------------------------------------------------------------
1 | using TonNurako.Widgets.Xm;
2 |
3 | namespace XmSeedtable
4 | {
5 | public partial class YamlToExcelDialogX11
6 | {
7 | private void Sinatra() {
8 | var form = new Form();
9 | form.Width = 320;
10 | form.Height = 320;
11 | this.Children.Add(form);
12 |
13 | var sc = new ScrolledWindow();
14 | form.Children.Add(sc);
15 |
16 | textBox = new Text();
17 | textBox.EditMode = EditMode.Multi;
18 |
19 | textBox.TopAttachment = AttachmentType.Form;
20 | textBox.LeftAttachment = AttachmentType.Form;
21 | textBox.RightAttachment = AttachmentType.Form;
22 | sc.Children.Add(textBox);
23 |
24 | okButton = new PushButton();
25 | okButton.LabelString = "閉じる";
26 | okButton.BottomAttachment = AttachmentType.Form;
27 | okButton.LeftAttachment = AttachmentType.Form;
28 | okButton.RightAttachment = AttachmentType.Form;
29 | okButton.ActivateEvent += (z,p) => {
30 | this.Destroy();
31 | };
32 | form.Children.Add(okButton);
33 | sc.BottomAttachment = AttachmentType.Widget;
34 | sc.BottomWidget = okButton;
35 | }
36 | private TonNurako.Widgets.Xm.PushButton okButton;
37 | private TonNurako.Widgets.Xm.Text textBox;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/seedtable/seedtable.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 | seedtable.ico
7 | seedtable
8 | SeedTable
9 | 4.0.1
10 | false
11 |
12 | Narazaka
13 | MIT
14 | https://github.com/seed-ui/seedtable
15 | https://github.com/seed-ui/seedtable
16 | GitHub
17 |
18 |
19 |
20 | 0.94.2
21 |
22 |
23 | 2.8.0
24 |
25 |
26 | 2.11.0
27 |
28 |
29 | 4.5.3.3
30 |
31 |
32 | 8.1.2
33 |
34 |
35 |
--------------------------------------------------------------------------------
/seedtable-test/ToTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class ToTest : FromToTestBase {
13 | [Theory]
14 | [InlineData(true)]
15 | [InlineData(false)]
16 | public void EqualToExample(bool delete) {
17 | var toOptions = BuildToOptions(Paths.ToSeedPath, Paths.TestResourcesPath, Paths.DestinationSeedPath());
18 | toOptions.delete = delete;
19 | var fromOptions = BuildFromOptions(toOptions.output, toOptions.output);
20 | Prepare(toOptions);
21 | Prepare(fromOptions);
22 |
23 | var comparePath = delete ? Paths.ToDeleteSeedPath : Paths.ToUnionSeedPath;
24 | foreach (var sourcePath in Directory.GetFiles(comparePath)) {
25 | var filename = Path.GetFileName(sourcePath);
26 | var destinationPath = Path.Combine(fromOptions.output, filename);
27 | Assert.True(File.Exists(destinationPath));
28 | var sourceContent = YamlData.YamlToData(File.ReadAllText(sourcePath)).Table;
29 | var destinationContent = YamlData.YamlToData(File.ReadAllText(destinationPath)).Table;
30 | Assert.Equal(sourceContent, destinationContent);
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/seedtable-gui/seedtable-gui.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | WinExe
4 | netcoreapp3.1
5 | true
6 | seedtable-gui
7 | seedtable_gui
8 | 4.0.1
9 | Narazaka
10 |
11 | MIT
12 | https://github.com/seed-ui/seedtable
13 | https://github.com/seed-ui/seedtable.git
14 | seedtable-gui.ico
15 | seedtable
16 |
17 |
18 |
19 | SettingsSingleFileGenerator
20 | Settings.Designer.cs
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {8bd2867d-75b8-4da7-9e62-b23e994cd3a0}
31 | seedtable
32 |
33 |
34 |
35 |
36 | 8.1.2
37 |
38 |
39 |
--------------------------------------------------------------------------------
/seedtable-test/WildcardsTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class WildcardsTest {
13 | public static IEnumerable Examples() {
14 | yield return new object[] {
15 | new string[] { "abc", "efg" },
16 | new string[] { "abc", "efg" },
17 | new string[] { "adc", "" },
18 | };
19 | yield return new object[] {
20 | new string[] { "a?c", "abcd" },
21 | new string[] { "abc", "adc", "abcd" },
22 | new string[] { "ac" },
23 | };
24 | yield return new object[] {
25 | new string[] { "a*c", "e?g" },
26 | new string[] { "abc", "abbc", "efg" },
27 | new string[] { "abcd", "a", "effg" },
28 | };
29 | }
30 |
31 | [Theory]
32 | [MemberData(nameof(Examples))]
33 | public void Wildcards(string[] wildcardStrs, string[] matches, string[] notMatches) {
34 | var wildcards = new Wildcards(wildcardStrs.Select(wildcardStr => new Wildcard(wildcardStr)));
35 | foreach (var match in matches) {
36 | Assert.True(wildcards.Contains(match));
37 | }
38 | foreach (var notMatch in notMatches) {
39 | Assert.False(wildcards.Contains(notMatch));
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/seedtable-test/SheetNameMapsTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class SheetNameMapsTest {
13 | public static IEnumerable Examples() {
14 | yield return new object[] { "fooX.xlsx", "fooX", "foos" };
15 | yield return new object[] { "fooX.xlsx", "fooY", null };
16 | yield return new object[] { "bar2.xlsx", "barX", "bars" };
17 | yield return new object[] { "bar2.xlsx", "barY", null };
18 | yield return new object[] { "my.xlsx", "bazbaz", "baz" };
19 | yield return new object[] { "my.xlsx", "bazbaz2", null };
20 | yield return new object[] { "my2.xlsx", "bazbaz", "baz2" };
21 | yield return new object[] { "my2.xlsx", "bazbaz2", null };
22 | }
23 |
24 | public static IEnumerable sheetNameMapStrs = new List {
25 | "foos:fooX",
26 | "bars:barX",
27 | "baz:my.xlsx/bazbaz",
28 | "baz2:my*.xlsx/bazbaz",
29 | };
30 |
31 | [Theory]
32 | [MemberData(nameof(Examples))]
33 | public void Parse(string fileName, string sheetName, string yamlTableName) {
34 | var sheetNameMaps = SheetNameMaps.FromMixed(sheetNameMapStrs);
35 | var sheetNameMap = sheetNameMaps.Find(fileName, sheetName);
36 | Assert.Equal(yamlTableName, sheetNameMap == null ? null : sheetNameMap.YamlTableName);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/ExcelToYamlDialogX11.Sinatra.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.Text;
6 | using System.Text.RegularExpressions;
7 | using TonNurako.Data;
8 | using TonNurako.Widgets;
9 | using TonNurako.Widgets.Xm;
10 |
11 | namespace XmSeedtable
12 | {
13 | public partial class ExcelToYamlDialogX11
14 | {
15 | private void Sinatra() {
16 | var form = new Form();
17 | form.Width = 320;
18 | form.Height = 320;
19 | this.Children.Add(form);
20 |
21 | var sc = new ScrolledWindow();
22 | form.Children.Add(sc);
23 |
24 | textBox = new Text();
25 | textBox.EditMode = EditMode.Multi;
26 |
27 | textBox.TopAttachment = AttachmentType.Form;
28 | textBox.LeftAttachment = AttachmentType.Form;
29 | textBox.RightAttachment = AttachmentType.Form;
30 | sc.Children.Add(textBox);
31 |
32 | okButton = new PushButton();
33 | okButton.LabelString = "閉じる";
34 | okButton.BottomAttachment = AttachmentType.Form;
35 | okButton.LeftAttachment = AttachmentType.Form;
36 | okButton.RightAttachment = AttachmentType.Form;
37 | okButton.ActivateEvent += (z,p) => {
38 | this.Destroy();
39 | };
40 | form.Children.Add(okButton);
41 | sc.BottomAttachment = AttachmentType.Widget;
42 | sc.BottomWidget = okButton;
43 | }
44 | private TonNurako.Widgets.Xm.PushButton okButton;
45 | private TonNurako.Widgets.Xm.Text textBox;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/seedtable/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using CommandLine;
3 |
4 | namespace SeedTable {
5 | class MainClass {
6 | public static void Main(string[] args) {
7 | SeedTableInterface.InformationMessageEvent += (message) => Console.Error.WriteLine(message);
8 | var options = CommandLine.Parser.Default.ParseArguments(args);
9 | try {
10 | options.MapResult(
11 | (FromOptions opts) => ExcelToSeed(opts),
12 | (ToOptions opts) => SeedToExcel(opts),
13 | error => true
14 | );
15 | } catch (SeedTableInterface.CannotContinueException) {
16 | Environment.Exit(1);
17 | }
18 | }
19 |
20 | static bool ExcelToSeed(FromOptions opts) {
21 | if (opts.config != null && opts.config.Length > 0) {
22 | opts = BasicOptions.Load(opts.config).FromOptions(
23 | files: opts.files,
24 | input: opts.input,
25 | output: opts.output
26 | );
27 | }
28 | return SeedTableInterface.ExcelToSeed(opts);
29 | }
30 |
31 | static bool SeedToExcel(ToOptions opts) {
32 | if (opts.config != null && opts.config.Length > 0) {
33 | opts = BasicOptions.Load(opts.config).ToOptions(
34 | files: opts.files,
35 | seedInput: opts.seedInput,
36 | xlsxInput: opts.xlsxInput,
37 | output: opts.output
38 | );
39 | }
40 | return SeedTableInterface.SeedToExcel(opts);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/seedtable-test/seedtable-test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 | false
6 | seedtable-test
7 | seedtable_test
8 | Narazaka
9 |
10 | seedtable
11 | MIT
12 | https://github.com/seed-ui/seedtable
13 | https://github.com/seed-ui/seedtable.git
14 | 4.0.1
15 |
16 |
17 |
18 |
19 |
20 |
21 | {8bd2867d-75b8-4da7-9e62-b23e994cd3a0}
22 | seedtable
23 |
24 |
25 |
26 |
27 | 2.4.1
28 |
29 |
30 | 2.4.1
31 | runtime; build; native; contentfiles; analyzers; buildtransitive
32 | all
33 |
34 |
35 | 2.4.1
36 | runtime; build; native; contentfiles; analyzers; buildtransitive
37 | all
38 |
39 |
40 |
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/SettingDialogX11.cs:
--------------------------------------------------------------------------------
1 | using SeedTable;
2 |
3 | namespace XmSeedtable
4 | {
5 | public partial class SettingDialogX11 :
6 | TonNurako.Widgets.Xm.DialogShell
7 | {
8 |
9 | BasicOptions Options { get; }
10 | SeedTableX11.SettingHandler XHandler {get;}
11 |
12 | bool Changable = false;
13 | public bool Status {get; private set;} = false;
14 | public SettingDialogX11(BasicOptions options,bool changeable, SeedTableX11.SettingHandler handler) : base() {
15 | this.Width = 700;
16 | this.Height = 600;
17 | Options = options;
18 | XHandler = handler;
19 | Changable = changeable;
20 | this.AllowAutoManage = false;
21 | this.AllowShellResize = true;
22 | this.Title = "Settings";
23 | this.CreatePopupChildEvent += (x,y) => {
24 | Sinatra();
25 | };
26 | this.PopdownEvent += (x,p) => {
27 | this.Destroy();
28 | };
29 | }
30 |
31 | void SaveOptions() {
32 | if(!Changable) {
33 | return;
34 | }
35 | Options.subdivide = subdivideTextBox.Value.Split('\n');
36 | Options.ignoreColumns = ignoreColumnsTextBox.Value.Split('\n');
37 | Options.yamlColumns = yamlColumnsTextBox.Value.Split('\n');
38 | Options.mapping = mappingTextBox.Value.Split('\n');
39 | Options.alias = aliasTextBox.Value.Split('\n');
40 | Options.ignore = ignoreTextBox.Value.Split('\n');
41 | Options.only = onlyTextBox.Value.Split('\n');
42 | Options.primary = primaryTextBox.Value.Split('\n');
43 | XHandler.Save(Options);
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/seedtable-test/AliasTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class AliasTest : FromToTestBase {
13 | private const string ExcelName = "seedtable_example_alias.xlsx";
14 | private readonly IEnumerable Alias = new string[] { "foos:foos_ref", "foos:foos_ref2" };
15 |
16 | [Fact]
17 | private void FromWithAlias() {
18 | var options = BuildFromOptions(new string[] { ExcelName });
19 | options.alias = Alias;
20 | Prepare(options);
21 | var files = Directory.GetFiles(options.output).Select(path => Path.GetFileName(path)).OrderBy(file => file);
22 | Assert.Equal(files, new string[] { "bars.yml", "foos.yml" });
23 | }
24 |
25 | [Fact]
26 | private void ToWithAlias() {
27 | var toOptions = BuildToOptions(new string[] { ExcelName }, Paths.AliasSeedPath, Paths.TestResourcesPath, Paths.DestinationSeedPath());
28 | toOptions.alias = Alias;
29 | toOptions.delete = true;
30 | var fromOptions = BuildFromOptions(new string[] { ExcelName }, toOptions.output, toOptions.output);
31 | Prepare(toOptions);
32 | Prepare(fromOptions);
33 |
34 | var sourceData = GetYamlData(Path.Combine(Paths.AliasSeedPath, "foos.yml"));
35 | foreach (var sheetName in new string[] { "foos", "foos_ref", "foos_ref2" }) {
36 | var data = GetYamlData(Path.Combine(toOptions.output, $"{sheetName}.yml"));
37 | Assert.Equal(sourceData, data);
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/seedtable-test/WildcardTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class WildcardTest {
13 | public static IEnumerable Examples() {
14 | yield return new object[] {
15 | "abc",
16 | new string[] { "abc" },
17 | new string[] { "adc", "abcd" },
18 | };
19 | yield return new object[] {
20 | "a?c",
21 | new string[] { "abc", "adc" },
22 | new string[] { "abcd", "ac" },
23 | };
24 | yield return new object[] {
25 | "a*c",
26 | new string[] { "abc", "abbc", "ac" },
27 | new string[] { "abcd", "a", "acd" },
28 | };
29 | yield return new object[] {
30 | "a*",
31 | new string[] { "abc", "a" },
32 | new string[] { "baa" },
33 | };
34 | yield return new object[] {
35 | "__*",
36 | new string[] { "__dummy", "__memo", "__" },
37 | new string[] { "_", "_a", "o" },
38 | };
39 | }
40 |
41 | [Theory]
42 | [MemberData(nameof(Examples))]
43 | public void Wildcard(string wildcardStr, string[] matches, string[] notMatches) {
44 | var wildcard = new Wildcard(wildcardStr);
45 | foreach (var match in matches) {
46 | Assert.True(wildcard.IsMatch(match));
47 | }
48 | foreach (var notMatch in notMatches) {
49 | Assert.False(wildcard.IsMatch(notMatch));
50 | }
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/YamlToExcelDialogX11.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using TonNurako.Widgets.Xm;
3 |
4 | using SeedTable;
5 | using System.Threading.Tasks;
6 |
7 | namespace XmSeedtable
8 | {
9 | public partial class YamlToExcelDialogX11 :
10 | TonNurako.Widgets.Xm.DialogShell
11 | {
12 |
13 | ToOptions Options { get; }
14 | public bool Status {get; private set;} = false;
15 | public YamlToExcelDialogX11(ToOptions options) : base() {
16 | Options = options;
17 | this.AllowAutoManage = false;
18 | this.DeleteResponse = DeleteResponse.DoNothing;
19 | this.CreatePopupChildEvent += (x,y) => {
20 | Sinatra();
21 | new Task(()=> {
22 | delegaty(options);
23 | }).Start();
24 | };
25 | }
26 |
27 | public void delegaty(ToOptions e) {
28 | this.AppContext.Invoke(()=>{
29 | okButton.Sensitive = false;
30 | });
31 | SeedTableInterface.InformationMessageEventHandler handler =
32 | (string message) => {
33 | Console.WriteLine(message);
34 | this.AppContext.Invoke(()=>{
35 | textBox.Insert(message + "\n", textBox.CursorPosition);
36 | });
37 | };
38 | SeedTableInterface.InformationMessageEvent += handler;
39 | try {
40 | SeedTableInterface.SeedToExcel(e);
41 | Status = true;
42 | } catch (SeedTableInterface.CannotContinueException) {
43 | Status = false;
44 | }
45 | finally {
46 | this.AppContext.Invoke(()=>{
47 | okButton.Sensitive = true;
48 | });
49 | SeedTableInterface.InformationMessageEvent -= handler;
50 | }
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/ExcelToYamlDialogX11.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using TonNurako.Widgets.Xm;
3 |
4 | using SeedTable;
5 | using System.Threading.Tasks;
6 |
7 | namespace XmSeedtable
8 | {
9 | public partial class ExcelToYamlDialogX11 :
10 | TonNurako.Widgets.Xm.DialogShell
11 | {
12 |
13 | FromOptions Options { get; }
14 | public bool Status {get; private set;} = false;
15 | public ExcelToYamlDialogX11(FromOptions options) : base() {
16 | Options = options;
17 | this.AllowAutoManage = false;
18 | this.DeleteResponse = DeleteResponse.DoNothing;
19 | this.CreatePopupChildEvent += (x,y) => {
20 | Sinatra();
21 | new Task(()=> {
22 | delegaty(options);
23 | }).Start();
24 | };
25 | }
26 |
27 | public void delegaty(FromOptions e) {
28 | this.AppContext.Invoke(()=>{
29 | okButton.Sensitive = false;
30 | });
31 | SeedTableInterface.InformationMessageEventHandler handler =
32 | (string message) => {
33 | Console.WriteLine(message);
34 | this.AppContext.Invoke(()=>{
35 | textBox.Insert(message + "\n", textBox.CursorPosition);
36 | });
37 | };
38 | SeedTableInterface.InformationMessageEvent += handler;
39 | try {
40 | SeedTableInterface.ExcelToSeed(e);
41 | Status = true;
42 | } catch (SeedTableInterface.CannotContinueException) {
43 | Status = false;
44 | }
45 | finally {
46 | this.AppContext.Invoke(()=>{
47 | okButton.Sensitive = true;
48 | });
49 | SeedTableInterface.InformationMessageEvent -= handler;
50 | }
51 |
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/XmSeedtable.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | netcoreapp3.1
5 | XmSeedTable
6 | XmSeedTable
7 | 4.0.1
8 | Narazaka
9 |
10 | MIT
11 | https://github.com/seed-ui/seedtable
12 | https://github.com/seed-ui/seedtable.git
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 |
--------------------------------------------------------------------------------
/seedtable-test/test-resources/seeds/datetimes.yml:
--------------------------------------------------------------------------------
1 | data1:
2 | id: 1
3 | date: 2015-01-01T00:00:00.0000000
4 | h:mm:ss: 1899-12-30T11:00:00.0000000
5 | time: 0.45833333333333331
6 | general_string: 2015-01-01T01:00:00
7 | datetime: 2015-01-01T11:00:13.0000000
8 | data2:
9 | id: 2
10 | date: 2015-01-02T00:00:00.0000000
11 | h:mm:ss: 1899-12-30T12:00:00.0000000
12 | time: 0.5
13 | general_string: 2015-01-01T01:00:01
14 | datetime: 2015-01-02T11:00:13.0000000
15 | data3:
16 | id: 3
17 | date: 2015-01-03T00:00:00.0000000
18 | h:mm:ss: 1899-12-30T13:00:00.0000000
19 | time: 0.54166666666666696
20 | general_string: 2015-01-01T01:00:02
21 | datetime: 2015-01-03T11:00:13.0000000
22 | data4:
23 | id: 4
24 | date: 2015-01-04T00:00:00.0000000
25 | h:mm:ss: 1899-12-30T14:00:00.0000000
26 | time: 0.58333333333333304
27 | general_string: 2015-01-01T01:00:03
28 | datetime: 2015-01-04T11:00:13.0000000
29 | data5:
30 | id: 5
31 | date: 2015-01-05T00:00:00.0000000
32 | h:mm:ss: 1899-12-30T15:00:00.0000000
33 | time: 0.625
34 | general_string: 2015-01-01T01:00:04
35 | datetime: 2015-01-05T11:00:13.0000000
36 | data6:
37 | id: 6
38 | date: 2015-01-06T00:00:00.0000000
39 | h:mm:ss: 1899-12-30T16:00:00.0000000
40 | time: 0.66666666666666696
41 | general_string: 2015-01-01T01:00:05
42 | datetime: 2015-01-06T11:00:13.0000000
43 | data7:
44 | id: 7
45 | date: 2015-01-07T00:00:00.0000000
46 | h:mm:ss: 1899-12-30T17:00:00.0000000
47 | time: 0.70833333333333304
48 | general_string: 2015-01-01T01:00:06
49 | datetime: 2015-01-07T11:00:13.0000000
50 | data8:
51 | id: 8
52 | date: 2015-01-08T00:00:00.0000000
53 | h:mm:ss: 1899-12-30T18:00:00.0000000
54 | time: 0.75
55 | general_string: 2015-01-01T01:00:07
56 | datetime: 2015-01-08T11:00:13.0000000
57 | data9:
58 | id: 9
59 | date: 2015-01-09T00:00:00.0000000
60 | h:mm:ss: 1899-12-30T19:00:00.0000000
61 | time: 0.79166666666666696
62 | general_string: 2015-01-01T01:00:08
63 | datetime: 2015-01-09T11:00:13.0000000
64 |
--------------------------------------------------------------------------------
/seedtable-egui/Pages/_Host.cshtml:
--------------------------------------------------------------------------------
1 | @page "/"
2 | @namespace seedtable_egui.Pages
3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
4 | @{
5 | Layout = null;
6 | }
7 |
8 |
9 |
10 |
11 |
12 |
13 | seedtable-egui
14 |
15 |
16 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | An error has occurred. This application may no longer respond until reloaded.
51 |
52 |
53 | An unhandled exception has occurred. See browser dev tools for details.
54 |
55 |
Reload
56 |
🗙
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/seedtable-egui/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.AspNetCore.Components;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using Microsoft.Extensions.Hosting;
11 | using ElectronNET.API;
12 | using ElectronNET.API.Entities;
13 | using seedtable_egui.Data;
14 |
15 | namespace seedtable_egui {
16 | public class Startup {
17 | public Startup(IConfiguration configuration) {
18 | Configuration = configuration;
19 | }
20 |
21 | public IConfiguration Configuration { get; }
22 |
23 | // This method gets called by the runtime. Use this method to add services to the container.
24 | // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
25 | public void ConfigureServices(IServiceCollection services) {
26 | services.AddRazorPages();
27 | services.AddServerSideBlazor();
28 | // services.AddSingleton();
29 | }
30 |
31 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
32 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
33 | if (env.IsDevelopment()) {
34 | app.UseDeveloperExceptionPage();
35 | } else {
36 | app.UseExceptionHandler("/Error");
37 | }
38 |
39 | app.UseStaticFiles();
40 |
41 | app.UseRouting();
42 |
43 | app.UseEndpoints(endpoints => {
44 | endpoints.MapBlazorHub();
45 | endpoints.MapFallbackToPage("/_Host");
46 | });
47 |
48 | Electron.WindowManager.CreateWindowAsync(new BrowserWindowOptions {
49 | Width = 360,
50 | Height = 260,
51 | AutoHideMenuBar = true,
52 | });
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/seedtable-gui/YamlToExcelDialog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using SeedTable;
11 |
12 | namespace seedtable_gui {
13 | public partial class YamlToExcelDialog : BaseForm {
14 | ToOptions Options { get; }
15 |
16 | public YamlToExcelDialog(ToOptions options) : base() {
17 | InitializeComponent();
18 | Options = options;
19 | }
20 |
21 | private void YamlToExcelDialog_Shown(object sender, EventArgs e) {
22 | seedToExcelBackgroundWorker.RunWorkerAsync(Options);
23 | }
24 |
25 | private void okButton_Click(object sender, EventArgs e) {
26 | Close();
27 | }
28 |
29 | private void seedToExcelBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
30 | var worker = sender as BackgroundWorker;
31 | SeedTableInterface.InformationMessageEventHandler handler =
32 | (string message) => worker.ReportProgress(0, message);
33 | SeedTableInterface.InformationMessageEvent += handler;
34 | try {
35 | SeedTableInterface.SeedToExcel((ToOptions)e.Argument);
36 | e.Result = true;
37 | } catch (SeedTableInterface.CannotContinueException) {
38 | e.Result = false;
39 | }
40 | SeedTableInterface.InformationMessageEvent -= handler;
41 | }
42 |
43 | private void WriteInfo(string message) {
44 | infoTextBox.AppendText(message + Environment.NewLine);
45 | }
46 |
47 | private void seedToExcelBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
48 | WriteInfo((string)e.UserState);
49 | }
50 |
51 | private void seedToExcelBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
52 | if ((bool)e.Result == false) {
53 | MessageBox.Show("処理が失敗しました");
54 | }
55 | okButton.Enabled = true;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/seedtable-gui/ExcelToYamlDialog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 | using SeedTable;
11 |
12 | namespace seedtable_gui {
13 | public partial class ExcelToYamlDialog : BaseForm {
14 | FromOptions Options { get; }
15 |
16 | public ExcelToYamlDialog(FromOptions options) : base() {
17 | InitializeComponent();
18 | Options = options;
19 | }
20 |
21 | private void ExcelToYamlDialog_Shown(object sender, EventArgs e) {
22 | excelToSeedBackgroundWorker.RunWorkerAsync(Options);
23 | }
24 |
25 | private void okButton_Click(object sender, EventArgs e) {
26 | Close();
27 | }
28 |
29 | private void excelToSeedBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
30 | var worker = sender as BackgroundWorker;
31 | SeedTableInterface.InformationMessageEventHandler handler =
32 | (string message) => worker.ReportProgress(0, message);
33 | SeedTableInterface.InformationMessageEvent += handler;
34 | try {
35 | SeedTableInterface.ExcelToSeed((FromOptions)e.Argument);
36 | e.Result = true;
37 | } catch (SeedTableInterface.CannotContinueException) {
38 | e.Result = false;
39 | }
40 | SeedTableInterface.InformationMessageEvent -= handler;
41 | }
42 |
43 | private void WriteInfo(string message) {
44 | infoTextBox.AppendText(message + Environment.NewLine);
45 | }
46 |
47 | private void excelToSeedBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
48 | WriteInfo((string)e.UserState);
49 | }
50 |
51 | private void excelToSeedBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
52 | if ((bool)e.Result == false) {
53 | MessageBox.Show("処理が失敗しました");
54 | }
55 | okButton.Enabled = true;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/seedtable-test/test-resources/seeds_to_union/datetimes.yml:
--------------------------------------------------------------------------------
1 | data1:
2 | id: 1
3 | date: 2015-01-01T00:00:00.0000000
4 | h:mm:ss: 1899-12-30T11:00:00.0000000
5 | time: 0.45833333333333331
6 | general_string: 2015-01-01T01:00:00
7 | datetime: 2015-01-01T11:00:13.0000000
8 | data2:
9 | id: 2
10 | date: 2015-01-02T00:00:00.0000000
11 | h:mm:ss: 1899-12-30T12:00:00.0000000
12 | time: 0.5
13 | general_string: 2015-01-01T01:00:01
14 | datetime: 2015-01-02T11:00:13.0000000
15 | data3:
16 | id: 3
17 | date: 2015-01-03T00:00:00.0000000
18 | h:mm:ss: 1899-12-30T13:00:00.0000000
19 | time: 0.54166666666666696
20 | general_string: 2015-01-01T01:00:02
21 | datetime: 2015-01-03T11:00:13.0000000
22 | data4:
23 | id: 4
24 | date: 2015-01-04T00:00:00.0000000
25 | h:mm:ss: 1899-12-30T14:00:00.0000000
26 | time: 0.58333333333333304
27 | general_string: 2015-01-01T01:00:03
28 | datetime: 2015-01-04T11:00:13.0000000
29 | data5:
30 | id: 5
31 | date: 2015-01-05T00:00:00.0000000
32 | h:mm:ss: 1899-12-30T15:00:00.0000000
33 | time: 0.625
34 | general_string: 2015-01-01T01:00:04
35 | datetime: 2015-01-05T11:00:13.0000000
36 | data6:
37 | id: 6
38 | date: 2015-01-06T00:00:00.0000000
39 | h:mm:ss: 1899-12-30T16:00:00.0000000
40 | time: 0.66666666666666696
41 | general_string: 2015-01-01T01:00:05
42 | datetime: 2015-01-06T11:00:13.0000000
43 | data7:
44 | id: 7
45 | date: 2015-01-07T00:00:00.0000000
46 | h:mm:ss: 1899-12-30T17:00:00.0000000
47 | time: 0.70833333333333304
48 | general_string: 2015-01-01T01:00:06
49 | datetime: 2015-01-07T11:00:13.0000000
50 | data8:
51 | id: 8
52 | date: 2015-01-08T00:00:00.0000000
53 | h:mm:ss: 1899-12-30T18:00:00.0000000
54 | time: 0.75
55 | general_string: 2015-01-01T01:00:07
56 | datetime: 2015-01-08T11:00:13.0000000
57 | data9:
58 | id: 9
59 | date: 2015-01-10T00:00:00.0000000
60 | h:mm:ss: 1899-12-30T20:00:00.0000000
61 | time: 0.79166666666666696
62 | general_string: 2015-01-01T01:00:09
63 | datetime: 2015-01-10T11:00:13.0000000
64 | data10:
65 | id: 10
66 | date: 2015-01-10T00:00:00.0000000
67 | h:mm:ss: 1899-12-30T20:00:00.0000000
68 | time: 0.79166666666666696
69 | general_string: 2015-01-01T01:00:09
70 | datetime: 2015-01-10T11:00:13.0000000
71 |
--------------------------------------------------------------------------------
/seedtable/Wildcard.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace SeedTable {
6 | public class Wildcards : List where T : Wildcard {
7 | public Wildcards() : base() { }
8 |
9 | public Wildcards(IEnumerable wildcards) : base(
10 | wildcards.Where(
11 | wildcard => wildcard.MatchType == WildcardMatchType.Exact
12 | ).Concat(
13 | wildcards.Where(
14 | wildcard => wildcard.MatchType == WildcardMatchType.Wildcard
15 | )
16 | ).Concat(
17 | wildcards.Where(
18 | wildcard => wildcard.MatchType == WildcardMatchType.All
19 | ).Take(1)
20 | )
21 | ) { }
22 |
23 | public T Find(string name) {
24 | return Find(matchName => matchName.IsMatch(name));
25 | }
26 |
27 | public bool Contains(string name) {
28 | return Find(name) != null;
29 | }
30 | }
31 |
32 | public class Wildcard {
33 | public string Name { get; }
34 | public WildcardMatchType MatchType { get; }
35 | private Regex NameMatcher { get; }
36 |
37 | public Wildcard(string name) {
38 | Name = name;
39 | if (Name == "*") {
40 | MatchType = WildcardMatchType.All;
41 | } else if (Name.Contains("*") || Name.Contains("?")) {
42 | NameMatcher = new Regex("^" + Regex.Escape(name).Replace(@"\*", ".*").Replace(@"\?", ".") + "$");
43 | MatchType = WildcardMatchType.Wildcard;
44 | } else {
45 | MatchType = WildcardMatchType.Exact;
46 | }
47 | }
48 |
49 | public bool IsMatch(string name) {
50 | switch (MatchType) {
51 | case WildcardMatchType.Exact:
52 | return name == Name;
53 | case WildcardMatchType.Wildcard:
54 | return NameMatcher.IsMatch(name);
55 | default:
56 | return true;
57 | }
58 | }
59 | }
60 |
61 | public enum WildcardMatchType {
62 | All = 0,
63 | Wildcard,
64 | Exact,
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/seedtable/SeedTable.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace SeedTable {
6 | interface IExcelData : IDisposable {
7 | IEnumerable SheetNames { get; }
8 | SeedTableBase GetSeedTable(string sheetName, int columnNamesRowIndex = 2, int dataStartRowIndex = 3, IEnumerable ignoreColumnNames = null, string keyColumnName = "id", string versionColumnName = null);
9 | void Save();
10 | void SaveAs(string file);
11 | }
12 |
13 | abstract class SeedTableBase {
14 | public int ColumnNamesRowIndex { get; }
15 | public int DataStartRowIndex { get; }
16 | public Wildcards IgnoreColumnNames { get; }
17 | public string KeyColumnName { get; }
18 | public string VersionColumnName { get; }
19 |
20 | public List Errors { get; protected set; } = new List();
21 |
22 | public SeedTableBase(int columnNamesRowIndex = 2, int dataStartRowIndex = 3, IEnumerable ignoreColumnNames = null, string keyColumnName = "id", string versionColumnName = null) {
23 | ColumnNamesRowIndex = columnNamesRowIndex;
24 | DataStartRowIndex = dataStartRowIndex;
25 | IgnoreColumnNames =
26 | ignoreColumnNames == null ?
27 | new Wildcards() :
28 | new Wildcards(ignoreColumnNames.Select(ignoreColumnName => new Wildcard(ignoreColumnName)));
29 | KeyColumnName = keyColumnName;
30 | VersionColumnName = versionColumnName;
31 | }
32 |
33 | public abstract string SheetName { get; }
34 | public abstract DataDictionaryList ExcelToData(string requireVersion = "");
35 | public abstract void DataToExcel(DataDictionaryList data, bool delete = false);
36 | }
37 |
38 | class DuplicateColumnNameException : InvalidOperationException {
39 | public DuplicateColumnNameException(string message) : base(message) { }
40 | }
41 |
42 | class NoIdColumnException : NotSupportedException {
43 | public NoIdColumnException(string message) : base(message) { }
44 | }
45 |
46 | class IdParseException : InvalidOperationException {
47 | public IdParseException(string id, Exception innerException) : base($"cannot parse id [{id}] as integer", innerException) { }
48 | }
49 |
50 | class SheetNotFoundException : InvalidOperationException {
51 | public SheetNotFoundException(string message, Exception innerException) : base(message, innerException) { }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/seedtable-test/FromToTestBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class FromToTestBase : IDisposable {
13 | private readonly List OptionsList = new List();
14 |
15 | protected virtual FromOptions BuildFromOptions(string input = null, string output = null) {
16 | return BuildFromOptions(new string[] { Paths.SourceExcelName }, input, output);
17 | }
18 |
19 | protected virtual FromOptions BuildFromOptions(IEnumerable files, string input = null, string output = null) {
20 | var options = new FromOptions();
21 | options.files = files;
22 | options.engine = CommonOptions.Engine.EPPlus;
23 | options.yamlColumns = new string[] { "data_yaml" };
24 | options.input = input ?? Paths.TestResourcesPath;
25 | options.output = output ?? Paths.DestinationSeedPath();
26 | OptionsList.Add(options);
27 | return options;
28 | }
29 |
30 | protected void Prepare(FromOptions options) {
31 | SeedTableInterface.ExcelToSeed(options);
32 | }
33 |
34 | protected virtual ToOptions BuildToOptions(string seedInput, string xlsxInput, string output, bool calcFormulas = true) {
35 | return BuildToOptions(new string[] { Paths.SourceExcelName }, seedInput, xlsxInput, output, calcFormulas);
36 | }
37 |
38 | protected virtual ToOptions BuildToOptions(IEnumerable files, string seedInput, string xlsxInput, string output, bool calcFormulas = true) {
39 | var options = new ToOptions();
40 | options.files = files;
41 | options.engine = CommonOptions.Engine.EPPlus;
42 | options.calcFormulas = calcFormulas;
43 | options.xlsxInput = xlsxInput;
44 | options.seedInput = seedInput;
45 | options.output = output;
46 | OptionsList.Add(options);
47 | return options;
48 | }
49 |
50 | protected void Prepare(ToOptions options) {
51 | SeedTableInterface.SeedToExcel(options);
52 | }
53 |
54 | protected IEnumerable> GetYamlData(string path) {
55 | return YamlData.YamlToData(File.ReadAllText(path)).Table;
56 | }
57 |
58 | public void Dispose() {
59 | foreach (var output in OptionsList.Select(options => options.output).Distinct()) {
60 | Directory.Delete(output, true);
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/seedtable/SheetsConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace SeedTable {
5 | class SheetsConfig {
6 | public SheetsConfig(
7 | IEnumerable only,
8 | IEnumerable ignore,
9 | IEnumerable subdivide = null,
10 | IEnumerable primary = null,
11 | IEnumerable mapping = null,
12 | IEnumerable alias = null
13 | ) {
14 | var subdivideSheetNames = SheetNameWithSubdivides.FromMixed(subdivide);
15 | OnlySheetNames = SheetNameWithSubdivides.FromMixed(only);
16 | IgnoreSheetNames = SheetNameWithSubdivides.FromMixed(ignore);
17 | SubdivideRules = new SheetNameWithSubdivides(subdivideSheetNames.Concat(OnlySheetNames));
18 | PrimarySheetNames = SheetNameOnFileNames.FromMixed(primary);
19 | excelToYamlMapping = SheetNameMaps.FromMixed(mapping);
20 | excelToYamlAlias = SheetNameMaps.FromMixed(alias);
21 | }
22 |
23 | SheetNameWithSubdivides SubdivideRules;
24 | SheetNameWithSubdivides IgnoreSheetNames;
25 | SheetNameWithSubdivides OnlySheetNames;
26 | SheetNameOnFileNames PrimarySheetNames;
27 | SheetNameMaps excelToYamlMapping;
28 | SheetNameMaps excelToYamlAlias;
29 |
30 | // onOperationはFrom | Toだと正しく動作しない
31 | public bool IsUseSheet(string fileName, string excelSheetName, string yamlTableName, OnOperation onOperation) {
32 | if (IgnoreSheetNames.Contains(fileName, yamlTableName, onOperation)) return false;
33 | if (OnlySheetNames.Count != 0 && !OnlySheetNames.Contains(fileName, yamlTableName, onOperation)) return false;
34 | if (onOperation.HasFlag(OnOperation.From)) {
35 | // TODO: primaryでない的なnoticeを出したほうが良い
36 | if (!PrimarySheetNames.IsUseSheet(fileName, yamlTableName)) return false;
37 | // エイリアス設定先のシートはfrom時変換されない
38 | if (excelToYamlAlias.Contains(fileName, excelSheetName)) return false;
39 | }
40 | return true;
41 | }
42 |
43 | public SheetNameWithSubdivide subdivide(string fileName, string sheetName, OnOperation onOperation) {
44 | var subdivideRule = SubdivideRules.Find(fileName, sheetName, onOperation);
45 | return subdivideRule ?? new SheetNameWithSubdivide(fileName, sheetName);
46 | }
47 |
48 | public string YamlTableName(string fileName, string excelSheetName) {
49 | var sheetNameMap = excelToYamlMapping.Find(fileName, excelSheetName) ?? excelToYamlAlias.Find(fileName, excelSheetName);
50 | return sheetNameMap == null ? excelSheetName : sheetNameMap.YamlTableName;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: csharp
2 | mono: none
3 | dotnet: 3.1.100
4 | solution: seedtable-x11/XmSeedtable.sln
5 | os: osx
6 | osx_image: xcode11.5
7 | matrix:
8 | include:
9 | - script:
10 | - dotnet restore seedtable-test
11 | - dotnet test seedtable-test
12 | - script:
13 | - dotnet tool install ElectronNET.CLI -g --version 8.31.1
14 | - npm install -g electron-builder
15 | - sh publish-egui-osx.sh
16 | - sh releases-egui-osx.sh
17 | deploy:
18 | provider: releases
19 | api_key:
20 | secure: "wD4X0IESRzhZoiemT88QMZRTo0WxDIwHZ/eHN/ee6DwoR8b6WrKQ0j31r+eT6XWE+BTeHwDdh3YASgL4VBpql65KQ3LMoKeq1ODl2cXqXTNSa220ArPf+5qmNhpAzSFUqa3gBil1D9fZnnzHCiDNAA4fEVbcEF7hvXHjfUN+Fbt/6sQDACtZmjiG507py5yjK0ZkrOl8vbuMbZcFkA0iQTpQVY1GsSwBiupRLF/+2KwV2/9SXgL3ZAEHTUUbfGgnV810EjxpPEotFi4xjFhEQvqcTfpJTQtFrfpGiCLScXKIelD1NFpj3E/1xxCA3txybEQImlkQQaoayyxfMUnGFENmRS6izNISFeF/Ayal24JAfy0Tez3p65Gr7cCY6thdLMrsxR0l1R/maO4DhFPr04H5CI81gEHq1o3+602RpyQDwmTeI0NPuNZdAtSLGWYKsBTi1C9zHtAUprkkqhJTyYhAX+XBRI4WCrpEybQanO1Fk4rPsT+vzV+4+6yxyxY37kRbECLJ+3p0qplNCUST92TzqOXXh+pbpnkdy3BkwYhDl3EU5D7g09DEBC38a5UNQrVjOWJQ/qcBLIWgJGvBZa5RlMlN5UV52HJOIhwfTEt2sO1fxBn3UIwYdYlP+k8v1s2mkX4aaC2EMAdtG+kpV2o85qQVXENV/v0UdMrHjDQ="
21 | file: releases/seedtable-egui-osx.zip
22 | skip_cleanup: true
23 | on:
24 | tags: true
25 | - env:
26 | # - XQUARTZ_VERSION=2.7.8
27 | - PKG_CONFIG_PATH=/opt/X11/lib/pkgconfig
28 | install:
29 | # - curl -L -O http://xquartz.macosforge.org/downloads/SL/XQuartz-${XQUARTZ_VERSION}.dmg
30 | # - hdiutil mount XQuartz-${XQUARTZ_VERSION}.dmg
31 | # - sudo installer -store -pkg /Volumes/XQuartz-${XQUARTZ_VERSION}/XQuartz.pkg -target /
32 | # - hdiutil unmount /Volumes/XQuartz-${XQUARTZ_VERSION}
33 | - brew update
34 | - brew install openmotif
35 | - dotnet restore seedtable
36 | - dotnet restore seedtable-x11/XmSeedtable
37 | script:
38 | - sh publish-xm-osx.sh
39 | - sh releases-xm-osx.sh
40 | deploy:
41 | provider: releases
42 | api_key:
43 | secure: "wD4X0IESRzhZoiemT88QMZRTo0WxDIwHZ/eHN/ee6DwoR8b6WrKQ0j31r+eT6XWE+BTeHwDdh3YASgL4VBpql65KQ3LMoKeq1ODl2cXqXTNSa220ArPf+5qmNhpAzSFUqa3gBil1D9fZnnzHCiDNAA4fEVbcEF7hvXHjfUN+Fbt/6sQDACtZmjiG507py5yjK0ZkrOl8vbuMbZcFkA0iQTpQVY1GsSwBiupRLF/+2KwV2/9SXgL3ZAEHTUUbfGgnV810EjxpPEotFi4xjFhEQvqcTfpJTQtFrfpGiCLScXKIelD1NFpj3E/1xxCA3txybEQImlkQQaoayyxfMUnGFENmRS6izNISFeF/Ayal24JAfy0Tez3p65Gr7cCY6thdLMrsxR0l1R/maO4DhFPr04H5CI81gEHq1o3+602RpyQDwmTeI0NPuNZdAtSLGWYKsBTi1C9zHtAUprkkqhJTyYhAX+XBRI4WCrpEybQanO1Fk4rPsT+vzV+4+6yxyxY37kRbECLJ+3p0qplNCUST92TzqOXXh+pbpnkdy3BkwYhDl3EU5D7g09DEBC38a5UNQrVjOWJQ/qcBLIWgJGvBZa5RlMlN5UV52HJOIhwfTEt2sO1fxBn3UIwYdYlP+k8v1s2mkX4aaC2EMAdtG+kpV2o85qQVXENV/v0UdMrHjDQ="
44 | file: releases/XmSeedtable-osx.zip
45 | skip_cleanup: true
46 | on:
47 | tags: true
48 |
--------------------------------------------------------------------------------
/seedtable-test/test-resources/seeds/foo_bars.yml:
--------------------------------------------------------------------------------
1 | data10001:
2 | id: 10001
3 | foo_id: 1
4 | dummy: 100
5 | value: 10000
6 | data10008:
7 | id: 10008
8 | foo_id: 1
9 | dummy: 100
10 | value: 10000
11 | data10015:
12 | id: 10015
13 | foo_id: 2
14 | dummy: 200
15 | value: 20000
16 | data10022:
17 | id: 10022
18 | foo_id: 2
19 | dummy: 200
20 | value: 20000
21 | data10029:
22 | id: 10029
23 | foo_id: 3
24 | dummy: 300
25 | value: 30000
26 | data10036:
27 | id: 10036
28 | foo_id: 3
29 | dummy: 300
30 | value: 30000
31 | data10043:
32 | id: 10043
33 | foo_id: 4
34 | dummy: 400
35 | value: 40000
36 | data10050:
37 | id: 10050
38 | foo_id: 4
39 | dummy: 400
40 | value: 40000
41 | data10057:
42 | id: 10057
43 | foo_id: 5
44 | dummy: 500
45 | value: 50000
46 | data10064:
47 | id: 10064
48 | foo_id: 5
49 | dummy: 500
50 | value: 50000
51 | data10071:
52 | id: 10071
53 | foo_id: 6
54 | dummy: 600
55 | value: 60000
56 | data10078:
57 | id: 10078
58 | foo_id: 6
59 | dummy: 600
60 | value: 60000
61 | data10085:
62 | id: 10085
63 | foo_id: 7
64 | dummy: 700
65 | value: 70000
66 | data10092:
67 | id: 10092
68 | foo_id: 7
69 | dummy: 700
70 | value: 70000
71 | data10099:
72 | id: 10099
73 | foo_id: 8
74 | dummy: 800
75 | value: 80000
76 | data10106:
77 | id: 10106
78 | foo_id: 8
79 | dummy: 800
80 | value: 80000
81 | data10113:
82 | id: 10113
83 | foo_id: 9
84 | dummy: 900
85 | value: 90000
86 | data10120:
87 | id: 10120
88 | foo_id: 9
89 | dummy: 900
90 | value: 90000
91 | data10127:
92 | id: 10127
93 | foo_id: 10
94 | dummy: 1000
95 | value: 100000
96 | data10134:
97 | id: 10134
98 | foo_id: 10
99 | dummy: 1000
100 | value: 100000
101 | data10141:
102 | id: 10141
103 | foo_id: 11
104 | dummy: 1100
105 | value: 110000
106 | data10148:
107 | id: 10148
108 | foo_id: 11
109 | dummy: 1100
110 | value: 110000
111 | data10155:
112 | id: 10155
113 | foo_id: 12
114 | dummy: 1200
115 | value: 120000
116 | data10162:
117 | id: 10162
118 | foo_id: 12
119 | dummy: 1200
120 | value: 120000
121 | data10169:
122 | id: 10169
123 | foo_id: 13
124 | dummy: 1300
125 | value: 130000
126 | data10176:
127 | id: 10176
128 | foo_id: 13
129 | dummy: 1300
130 | value: 130000
131 | data10183:
132 | id: 10183
133 | foo_id: 14
134 | dummy: 1400
135 | value: 140000
136 | data10190:
137 | id: 10190
138 | foo_id: 14
139 | dummy: 1400
140 | value: 140000
141 | data10197:
142 | id: 10197
143 | foo_id: 15
144 | dummy: 1500
145 | value: 150000
146 | data10204:
147 | id: 10204
148 | foo_id: 15
149 | dummy: 1500
150 | value: 150000
151 | data10211:
152 | id: 10211
153 | foo_id: 16
154 | dummy: 1600
155 | value: 160000
156 | data10218:
157 | id: 10218
158 | foo_id: 16
159 | dummy: 1600
160 | value: 160000
161 |
--------------------------------------------------------------------------------
/seedtable-test/test-resources/seeds_to_union/foo_bars.yml:
--------------------------------------------------------------------------------
1 | data10001:
2 | id: 10001
3 | foo_id: 1
4 | dummy: 100
5 | value: 10000
6 | data10008:
7 | id: 10008
8 | foo_id: 1
9 | dummy: 100
10 | value: 10000
11 | data10015:
12 | id: 10015
13 | foo_id: 3
14 | dummy: 300
15 | value: 30000
16 | data10022:
17 | id: 10022
18 | foo_id: 2
19 | dummy: 200
20 | value: 20000
21 | data10029:
22 | id: 10029
23 | foo_id: 3
24 | dummy: 300
25 | value: 30000
26 | data10036:
27 | id: 10036
28 | foo_id: 3
29 | dummy: 300
30 | value: 30000
31 | data10043:
32 | id: 10043
33 | foo_id: 4
34 | dummy: 400
35 | value: 40000
36 | data10050:
37 | id: 10050
38 | foo_id: 4
39 | dummy: 400
40 | value: 40000
41 | data10057:
42 | id: 10057
43 | foo_id: 5
44 | dummy: 500
45 | value: 50000
46 | data10064:
47 | id: 10064
48 | foo_id: 5
49 | dummy: 500
50 | value: 50000
51 | data10071:
52 | id: 10071
53 | foo_id: 6
54 | dummy: 600
55 | value: 60000
56 | data10078:
57 | id: 10078
58 | foo_id: 6
59 | dummy: 600
60 | value: 60000
61 | data10085:
62 | id: 10085
63 | foo_id: 7
64 | dummy: 700
65 | value: 70000
66 | data10092:
67 | id: 10092
68 | foo_id: 7
69 | dummy: 700
70 | value: 70000
71 | data10099:
72 | id: 10099
73 | foo_id: 8
74 | dummy: 800
75 | value: 80000
76 | data10106:
77 | id: 10106
78 | foo_id: 8
79 | dummy: 800
80 | value: 80000
81 | data10113:
82 | id: 10113
83 | foo_id: 9
84 | dummy: 900
85 | value: 90000
86 | data10120:
87 | id: 10120
88 | foo_id: 9
89 | dummy: 900
90 | value: 90000
91 | data10127:
92 | id: 10127
93 | foo_id: 10
94 | dummy: 1000
95 | value: 100000
96 | data10134:
97 | id: 10134
98 | foo_id: 10
99 | dummy: 1000
100 | value: 100000
101 | data10141:
102 | id: 10141
103 | foo_id: 11
104 | dummy: 1100
105 | value: 110000
106 | data10148:
107 | id: 10148
108 | foo_id: 11
109 | dummy: 1100
110 | value: 110000
111 | data10155:
112 | id: 10155
113 | foo_id: 12
114 | dummy: 1200
115 | value: 120000
116 | data10162:
117 | id: 10162
118 | foo_id: 12
119 | dummy: 1200
120 | value: 120000
121 | data10169:
122 | id: 10169
123 | foo_id: 13
124 | dummy: 1300
125 | value: 130000
126 | data10176:
127 | id: 10176
128 | foo_id: 13
129 | dummy: 1300
130 | value: 130000
131 | data10183:
132 | id: 10183
133 | foo_id: 14
134 | dummy: 1400
135 | value: 140000
136 | data10190:
137 | id: 10190
138 | foo_id: 14
139 | dummy: 1400
140 | value: 140000
141 | data10197:
142 | id: 10197
143 | foo_id: 15
144 | dummy: 1500
145 | value: 150000
146 | data10204:
147 | id: 10204
148 | foo_id: 15
149 | dummy: 1500
150 | value: 150000
151 | data10211:
152 | id: 10211
153 | foo_id: 16
154 | dummy: 1600
155 | value: 160000
156 | data10218:
157 | id: 10218
158 | foo_id: 16
159 | dummy: 1600
160 | value: 160000
161 | data10220:
162 | id: 10220
163 | foo_id: 16
164 | dummy: 1600
165 | value: 160000
166 |
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29609.76
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XmSeedtable", "XmSeedtable\XmSeedtable.csproj", "{0611BC07-926D-4AC7-A970-2CB939A43BE5}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TonNurako", "TonNurako2\TonNurako\TonNurako.csproj", "{936E32EA-D5CB-41B5-B75A-A282DB26CC1C}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "seedtable", "..\seedtable\seedtable.csproj", "{8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Debug|x86 = Debug|x86
16 | Release|Any CPU = Release|Any CPU
17 | Release|x86 = Release|x86
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {0611BC07-926D-4AC7-A970-2CB939A43BE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {0611BC07-926D-4AC7-A970-2CB939A43BE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {0611BC07-926D-4AC7-A970-2CB939A43BE5}.Debug|x86.ActiveCfg = Debug|Any CPU
23 | {0611BC07-926D-4AC7-A970-2CB939A43BE5}.Debug|x86.Build.0 = Debug|Any CPU
24 | {0611BC07-926D-4AC7-A970-2CB939A43BE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {0611BC07-926D-4AC7-A970-2CB939A43BE5}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {0611BC07-926D-4AC7-A970-2CB939A43BE5}.Release|x86.ActiveCfg = Release|Any CPU
27 | {0611BC07-926D-4AC7-A970-2CB939A43BE5}.Release|x86.Build.0 = Release|Any CPU
28 | {936E32EA-D5CB-41B5-B75A-A282DB26CC1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29 | {936E32EA-D5CB-41B5-B75A-A282DB26CC1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
30 | {936E32EA-D5CB-41B5-B75A-A282DB26CC1C}.Debug|x86.ActiveCfg = Debug|Any CPU
31 | {936E32EA-D5CB-41B5-B75A-A282DB26CC1C}.Debug|x86.Build.0 = Debug|Any CPU
32 | {936E32EA-D5CB-41B5-B75A-A282DB26CC1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {936E32EA-D5CB-41B5-B75A-A282DB26CC1C}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {936E32EA-D5CB-41B5-B75A-A282DB26CC1C}.Release|x86.ActiveCfg = Release|Any CPU
35 | {936E32EA-D5CB-41B5-B75A-A282DB26CC1C}.Release|x86.Build.0 = Release|Any CPU
36 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Debug|x86.ActiveCfg = Debug|Any CPU
39 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Debug|x86.Build.0 = Debug|Any CPU
40 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Release|Any CPU.Build.0 = Release|Any CPU
42 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Release|x86.ActiveCfg = Release|Any CPU
43 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Release|x86.Build.0 = Release|Any CPU
44 | EndGlobalSection
45 | GlobalSection(SolutionProperties) = preSolution
46 | HideSolutionNode = FALSE
47 | EndGlobalSection
48 | GlobalSection(ExtensibilityGlobals) = postSolution
49 | SolutionGuid = {298CB2F3-9F1A-478A-9428-F2130B301404}
50 | EndGlobalSection
51 | EndGlobal
52 |
--------------------------------------------------------------------------------
/seedtable-test/test-resources/seeds/foo_bar_bazs.yml:
--------------------------------------------------------------------------------
1 | data1:
2 | id: 1
3 | foo_bar_id: 10001
4 | dummy: 10000
5 | value: 1000000
6 | data2:
7 | id: 2
8 | foo_bar_id: 10008
9 | dummy: 10000
10 | value: 1000000
11 | data3:
12 | id: 3
13 | foo_bar_id: 10015
14 | dummy: 20000
15 | value: 2000000
16 | data4:
17 | id: 4
18 | foo_bar_id: 10022
19 | dummy: 20000
20 | value: 2000000
21 | data5:
22 | id: 5
23 | foo_bar_id: 10029
24 | dummy: 30000
25 | value: 3000000
26 | data6:
27 | id: 6
28 | foo_bar_id: 10036
29 | dummy: 30000
30 | value: 3000000
31 | data7:
32 | id: 7
33 | foo_bar_id: 10043
34 | dummy: 40000
35 | value: 4000000
36 | data8:
37 | id: 8
38 | foo_bar_id: 10050
39 | dummy: 40000
40 | value: 4000000
41 | data9:
42 | id: 9
43 | foo_bar_id: 10057
44 | dummy: 50000
45 | value: 5000000
46 | data10:
47 | id: 10
48 | foo_bar_id: 10064
49 | dummy: 50000
50 | value: 5000000
51 | data11:
52 | id: 11
53 | foo_bar_id: 10071
54 | dummy: 60000
55 | value: 6000000
56 | data12:
57 | id: 12
58 | foo_bar_id: 10078
59 | dummy: 60000
60 | value: 6000000
61 | data13:
62 | id: 13
63 | foo_bar_id: 10085
64 | dummy: 70000
65 | value: 7000000
66 | data14:
67 | id: 14
68 | foo_bar_id: 10092
69 | dummy: 70000
70 | value: 7000000
71 | data15:
72 | id: 15
73 | foo_bar_id: 10099
74 | dummy: 80000
75 | value: 8000000
76 | data16:
77 | id: 16
78 | foo_bar_id: 10106
79 | dummy: 80000
80 | value: 8000000
81 | data17:
82 | id: 17
83 | foo_bar_id: 10113
84 | dummy: 90000
85 | value: 9000000
86 | data18:
87 | id: 18
88 | foo_bar_id: 10120
89 | dummy: 90000
90 | value: 9000000
91 | data19:
92 | id: 19
93 | foo_bar_id: 10127
94 | dummy: 100000
95 | value: 10000000
96 | data20:
97 | id: 20
98 | foo_bar_id: 10134
99 | dummy: 100000
100 | value: 10000000
101 | data21:
102 | id: 21
103 | foo_bar_id: 10141
104 | dummy: 110000
105 | value: 11000000
106 | data22:
107 | id: 22
108 | foo_bar_id: 10148
109 | dummy: 110000
110 | value: 11000000
111 | data23:
112 | id: 23
113 | foo_bar_id: 10155
114 | dummy: 120000
115 | value: 12000000
116 | data24:
117 | id: 24
118 | foo_bar_id: 10162
119 | dummy: 120000
120 | value: 12000000
121 | data25:
122 | id: 25
123 | foo_bar_id: 10169
124 | dummy: 130000
125 | value: 13000000
126 | data26:
127 | id: 26
128 | foo_bar_id: 10176
129 | dummy: 130000
130 | value: 13000000
131 | data27:
132 | id: 27
133 | foo_bar_id: 10183
134 | dummy: 140000
135 | value: 14000000
136 | data28:
137 | id: 28
138 | foo_bar_id: 10190
139 | dummy: 140000
140 | value: 14000000
141 | data29:
142 | id: 29
143 | foo_bar_id: 10197
144 | dummy: 150000
145 | value: 15000000
146 | data30:
147 | id: 30
148 | foo_bar_id: 10204
149 | dummy: 150000
150 | value: 15000000
151 | data31:
152 | id: 31
153 | foo_bar_id: 10211
154 | dummy: 160000
155 | value: 16000000
156 | data32:
157 | id: 32
158 | foo_bar_id: 10218
159 | dummy: 160000
160 | value: 16000000
161 |
--------------------------------------------------------------------------------
/seedtable-test/test-resources/seeds_to_union/foo_bar_bazs.yml:
--------------------------------------------------------------------------------
1 | data1:
2 | id: 1
3 | foo_bar_id: 10001
4 | dummy: 10000
5 | value: 1000000
6 | data2:
7 | id: 2
8 | foo_bar_id: 10008
9 | dummy: 10000
10 | value: 1000000
11 | data3:
12 | id: 3
13 | foo_bar_id: 10015
14 | dummy: 30000
15 | value: 3000000
16 | data4:
17 | id: 4
18 | foo_bar_id: 10022
19 | dummy: 20000
20 | value: 2000000
21 | data5:
22 | id: 5
23 | foo_bar_id: 10029
24 | dummy: 30000
25 | value: 3000000
26 | data6:
27 | id: 6
28 | foo_bar_id: 10036
29 | dummy: 30000
30 | value: 3000000
31 | data7:
32 | id: 7
33 | foo_bar_id: 10043
34 | dummy: 40000
35 | value: 4000000
36 | data8:
37 | id: 8
38 | foo_bar_id: 10050
39 | dummy: 40000
40 | value: 4000000
41 | data9:
42 | id: 9
43 | foo_bar_id: 10057
44 | dummy: 50000
45 | value: 5000000
46 | data10:
47 | id: 10
48 | foo_bar_id: 10064
49 | dummy: 50000
50 | value: 5000000
51 | data11:
52 | id: 11
53 | foo_bar_id: 10071
54 | dummy: 60000
55 | value: 6000000
56 | data12:
57 | id: 12
58 | foo_bar_id: 10078
59 | dummy: 60000
60 | value: 6000000
61 | data13:
62 | id: 13
63 | foo_bar_id: 10085
64 | dummy: 70000
65 | value: 7000000
66 | data14:
67 | id: 14
68 | foo_bar_id: 10092
69 | dummy: 70000
70 | value: 7000000
71 | data15:
72 | id: 15
73 | foo_bar_id: 10099
74 | dummy: 80000
75 | value: 8000000
76 | data16:
77 | id: 16
78 | foo_bar_id: 10106
79 | dummy: 80000
80 | value: 8000000
81 | data17:
82 | id: 17
83 | foo_bar_id: 10113
84 | dummy: 90000
85 | value: 9000000
86 | data18:
87 | id: 18
88 | foo_bar_id: 10120
89 | dummy: 90000
90 | value: 9000000
91 | data19:
92 | id: 19
93 | foo_bar_id: 10127
94 | dummy: 100000
95 | value: 10000000
96 | data20:
97 | id: 20
98 | foo_bar_id: 10134
99 | dummy: 100000
100 | value: 10000000
101 | data21:
102 | id: 21
103 | foo_bar_id: 10141
104 | dummy: 110000
105 | value: 11000000
106 | data22:
107 | id: 22
108 | foo_bar_id: 10148
109 | dummy: 110000
110 | value: 11000000
111 | data23:
112 | id: 23
113 | foo_bar_id: 10155
114 | dummy: 120000
115 | value: 12000000
116 | data24:
117 | id: 24
118 | foo_bar_id: 10162
119 | dummy: 120000
120 | value: 12000000
121 | data25:
122 | id: 25
123 | foo_bar_id: 10169
124 | dummy: 130000
125 | value: 13000000
126 | data26:
127 | id: 26
128 | foo_bar_id: 10176
129 | dummy: 130000
130 | value: 13000000
131 | data27:
132 | id: 27
133 | foo_bar_id: 10183
134 | dummy: 140000
135 | value: 14000000
136 | data28:
137 | id: 28
138 | foo_bar_id: 10190
139 | dummy: 140000
140 | value: 14000000
141 | data29:
142 | id: 29
143 | foo_bar_id: 10197
144 | dummy: 150000
145 | value: 15000000
146 | data30:
147 | id: 30
148 | foo_bar_id: 10204
149 | dummy: 150000
150 | value: 15000000
151 | data31:
152 | id: 31
153 | foo_bar_id: 10211
154 | dummy: 160000
155 | value: 16000000
156 | data32:
157 | id: 32
158 | foo_bar_id: 10218
159 | dummy: 160000
160 | value: 16000000
161 |
--------------------------------------------------------------------------------
/seedtable/BasicOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.IO;
3 | using YamlDotNet.Serialization;
4 | using YamlDotNet.Serialization.NamingConventions;
5 |
6 | namespace SeedTable {
7 | public class BasicOptions : CommonBasicOptions, IBasicOptions {
8 | public IEnumerable yamlColumns { get; set; } = new List { };
9 |
10 | public IEnumerable primary { get; set; } = new List { };
11 |
12 | public bool calcFormulas { get; set; } = false;
13 |
14 | public FromOptions FromOptions(IEnumerable files = null, string input = ".", string output = ".") {
15 | return new FromOptions() {
16 | ignore = ignore,
17 | only = only,
18 | mapping = mapping,
19 | alias = alias,
20 | requireVersion = requireVersion,
21 | versionColumn = versionColumn,
22 | ignoreColumns = ignoreColumns,
23 | format = format,
24 | columnNamesRow = columnNamesRow,
25 | dataStartRow = dataStartRow,
26 | engine = engine,
27 | delete = delete,
28 | seedExtension = seedExtension,
29 | yamlColumns = yamlColumns,
30 | primary = primary,
31 | subdivide = subdivide,
32 | input = input,
33 | output = output,
34 | files = files,
35 | };
36 | }
37 |
38 | public ToOptions ToOptions(IEnumerable files = null, string seedInput = ".", string xlsxInput = ".", string output = ".") {
39 | return new ToOptions() {
40 | ignore = ignore,
41 | only = only,
42 | mapping = mapping,
43 | alias = alias,
44 | requireVersion = requireVersion,
45 | versionColumn = versionColumn,
46 | ignoreColumns = ignoreColumns,
47 | format = format,
48 | columnNamesRow = columnNamesRow,
49 | dataStartRow = dataStartRow,
50 | engine = engine,
51 | delete = delete,
52 | seedExtension = seedExtension,
53 | calcFormulas = calcFormulas,
54 | subdivide = subdivide,
55 | seedInput = seedInput,
56 | xlsxInput = xlsxInput,
57 | output = output,
58 | files = files,
59 | };
60 | }
61 |
62 | public static BasicOptions Load(string filepath) {
63 | var yaml = File.ReadAllText(filepath);
64 | var builder = new DeserializerBuilder();
65 | builder.WithNamingConvention(HyphenatedNamingConvention.Instance);
66 | builder.IgnoreUnmatchedProperties();
67 | var deserializer = builder.Build();
68 | var options = deserializer.Deserialize(yaml);
69 | return options ?? new BasicOptions();
70 | }
71 |
72 | public void Save(string filepath) {
73 | var builder = new SerializerBuilder();
74 | builder.WithNamingConvention(HyphenatedNamingConvention.Instance);
75 | var serializer = builder.Build();
76 | var yaml = serializer.Serialize(this);
77 | File.WriteAllText(filepath, yaml);
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/seedtable-x11/XmSeedtable/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // このコードはツールによって生成されました。
4 | // ランタイム バージョン:4.0.30319.42000
5 | //
6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
7 | // コードが再生成されるときに損失したりします。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace XmSeedtable.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。
17 | ///
18 | // このクラスは StronglyTypedResourceBuilder クラスが ResGen
19 | // または Visual Studio のようなツールを使用して自動生成されました。
20 | // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に
21 | // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XmSeedtable.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、
51 | /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// 型 System.Drawing.Bitmap のローカライズされたリソースを検索します。
65 | ///
66 | internal static byte[] excelToYaml {
67 | get {
68 | object obj = ResourceManager.GetObject("excelToYaml", resourceCulture);
69 | return ((byte[])(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// 型 System.Drawing.Bitmap のローカライズされたリソースを検索します。
75 | ///
76 | internal static byte[]yamlToExcel {
77 | get {
78 | object obj = ResourceManager.GetObject("yamlToExcel", resourceCulture);
79 | return ((byte[])(obj));
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/seedtable-test/SubdivideOptionTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class SubdivideOptionTest {
13 | public static IEnumerable Examples() {
14 | yield return new object[] { "foos", "NO_NAME", "foos", false, 0, 0, "id", null, null, OnOperation.From | OnOperation.To };
15 | yield return new object[] { "foo.xlsx/foos", "foo.xlsx", "foos", false, 0, 0, "id", null, null, OnOperation.From | OnOperation.To };
16 | yield return new object[] { "foos:0", "NO_NAME", "foos", true, 0, 0, "id", null, null, OnOperation.From | OnOperation.To };
17 | yield return new object[] { "0:foos", "NO_NAME", "foos", true, 0, 0, "id", null, null, OnOperation.From | OnOperation.To };
18 | yield return new object[] { "foos:1", "NO_NAME", "foos", true, 0, 1, "id", null, null, OnOperation.From | OnOperation.To };
19 | yield return new object[] { "1:foos", "NO_NAME", "foos", true, 1, 0, "id", null, null, OnOperation.From | OnOperation.To };
20 | yield return new object[] { "2:foos:2", "NO_NAME", "foos", true, 2, 2, "id", null, null, OnOperation.From | OnOperation.To };
21 | yield return new object[] { "foos@NO_OPTION", "NO_NAME", "foos", false, 0, 0, "id", null, null, OnOperation.From | OnOperation.To };
22 | yield return new object[] { "foos@from", "NO_NAME", "foos", false, 0, 0, "id", null, null, OnOperation.From };
23 | yield return new object[] { "foos@TO", "NO_NAME", "foos", false, 0, 0, "id", null, null, OnOperation.To };
24 | yield return new object[] { "foos@key=foo_id", "NO_NAME", "foos", false, 0, 0, "foo_id", null, null, OnOperation.From | OnOperation.To };
25 | yield return new object[] { "foos@column-names-row=9", "NO_NAME", "foos", false, 0, 0, "id", 9, null, OnOperation.From | OnOperation.To };
26 | yield return new object[] { "foos@data-start-row=10", "NO_NAME", "foos", false, 0, 0, "id", null, 10, OnOperation.From | OnOperation.To };
27 | yield return new object[] { "foos@from@key=foo_id", "NO_NAME", "foos", false, 0, 0, "foo_id", null, null, OnOperation.From };
28 | yield return new object[] { "1:foo.xlsx/foos:0@from@key=foo_id@column-names-row=9", "foo.xlsx", "foos", true, 1, 0, "foo_id", 9, null, OnOperation.From };
29 | }
30 |
31 | [Theory]
32 | [MemberData(nameof(Examples))]
33 | public void Parse(string subdivideStr, string fileName, string sheetName, bool needSubdivide, int cutPrefix, int cutPostfix, string keyColumnName, int? columnNamesRow, int? dataStartRow, OnOperation oonOperation) {
34 | var subdivide = SheetNameWithSubdivide.FromMixed(subdivideStr);
35 | Assert.True(subdivide.FileName.IsMatch(fileName));
36 | Assert.True(subdivide.SheetName.IsMatch(sheetName));
37 | Assert.Equal(subdivide.NeedSubdivide, needSubdivide);
38 | Assert.Equal(subdivide.CutPrefix, cutPrefix);
39 | Assert.Equal(subdivide.CutPostfix, cutPostfix);
40 | Assert.Equal(subdivide.KeyColumnName, keyColumnName);
41 | Assert.Equal(subdivide.ColumnNamesRow, columnNamesRow);
42 | Assert.Equal(subdivide.DataStartRow, dataStartRow);
43 | Assert.Equal(subdivide.OnOperation, oonOperation);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/seedtable-gui/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // このコードはツールによって生成されました。
4 | // ランタイム バージョン:4.0.30319.42000
5 | //
6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
7 | // コードが再生成されるときに損失したりします。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace seedtable_gui.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。
17 | ///
18 | // このクラスは StronglyTypedResourceBuilder クラスが ResGen
19 | // または Visual Studio のようなツールを使用して自動生成されました。
20 | // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に
21 | // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("seedtable_gui.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// すべてについて、現在のスレッドの CurrentUICulture プロパティをオーバーライドします
51 | /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// 型 System.Drawing.Bitmap のローカライズされたリソースを検索します。
65 | ///
66 | internal static System.Drawing.Bitmap excelToYaml {
67 | get {
68 | object obj = ResourceManager.GetObject("excelToYaml", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// 型 System.Drawing.Bitmap のローカライズされたリソースを検索します。
75 | ///
76 | internal static System.Drawing.Bitmap yamlToExcel {
77 | get {
78 | object obj = ResourceManager.GetObject("yamlToExcel", resourceCulture);
79 | return ((System.Drawing.Bitmap)(obj));
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/seedtable/SheetNameWithSubdivide.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace SeedTable {
5 | public class SheetNameWithSubdivide {
6 | public static SheetNameWithSubdivide FromMixed(string mixedName) {
7 | var result = Regex.Match(mixedName, @"^(?:(\d+):)?(?:([^:@]+)/)?([^:/@]+)(?::(\d+))?(?:@(.*))?$");
8 | if (!result.Success) throw new Exception($"{mixedName} is wrong sheet name and subdivide rule definition");
9 | var cutPrefixStr = result.Groups[1].Value;
10 | var fileName = result.Groups[2].Value;
11 | if (fileName.Length == 0) fileName = "*";
12 | var sheetName = result.Groups[3].Value;
13 | var cutPostfixStr = result.Groups[4].Value;
14 | var options = result.Groups[5].Value == null ? new string[] { } : result.Groups[5].Value.Split('@');
15 | var onOperation = OnOperation.From | OnOperation.To;
16 | var keyColumnName = "id";
17 | int? columnNamesRow = null;
18 | int? dataStartRow = null;
19 | string subdivideFilename = null;
20 | foreach (var option in options) {
21 | if (Regex.IsMatch(option, $"^(?:from|to)$", RegexOptions.IgnoreCase)) {
22 | Enum.TryParse(option, true, out onOperation);
23 | } else if (option.StartsWith("key=")) {
24 | keyColumnName = option.Substring(4);
25 | } else if (option.StartsWith("column-names-row=")) {
26 | columnNamesRow = int.Parse(option.Substring(17));
27 | } else if (option.StartsWith("data-start-row=")) {
28 | dataStartRow = int.Parse(option.Substring(15));
29 | } else if (option.StartsWith("subdivide-filename=")) {
30 | subdivideFilename = option.Substring(19);
31 | }
32 | }
33 | var needSubdivide = cutPrefixStr.Length != 0 || cutPostfixStr.Length != 0;
34 | var cutPrefix = cutPrefixStr.Length == 0 ? 0 : Convert.ToInt32(cutPrefixStr);
35 | var cutPostfix = cutPostfixStr.Length == 0 ? 0 : Convert.ToInt32(cutPostfixStr);
36 | return new SheetNameWithSubdivide(fileName, sheetName, needSubdivide, cutPrefix, cutPostfix, keyColumnName, columnNamesRow, dataStartRow, subdivideFilename, onOperation);
37 | }
38 |
39 | public Wildcard FileName { get; } = null;
40 | public Wildcard SheetName { get; }
41 | public bool NeedSubdivide { get; }
42 | public int CutPrefix { get; }
43 | public int CutPostfix { get; }
44 | public string KeyColumnName { get; }
45 | public int? ColumnNamesRow { get; }
46 | public int? DataStartRow { get; }
47 | public string SubdivideFilename { get; }
48 | public OnOperation OnOperation { get; }
49 |
50 | public SheetNameWithSubdivide(
51 | string fileName,
52 | string sheetName,
53 | bool needSubdivide = false,
54 | int cutPrefix = 0,
55 | int cutPostfix = 0,
56 | string keyColumnName = "id",
57 | int? columnNamesRow = null,
58 | int? dataStartRow = null,
59 | string subdivideFilename = null,
60 | OnOperation onOperation = OnOperation.From | OnOperation.To
61 | ) {
62 | FileName = new Wildcard(fileName);
63 | SheetName = new Wildcard(sheetName);
64 | NeedSubdivide = needSubdivide;
65 | CutPrefix = cutPrefix;
66 | CutPostfix = cutPostfix;
67 | KeyColumnName = keyColumnName;
68 | ColumnNamesRow = columnNamesRow;
69 | DataStartRow = dataStartRow;
70 | SubdivideFilename = subdivideFilename;
71 | OnOperation = onOperation;
72 | }
73 |
74 | public bool IsMatch(string fileName, string sheetName, OnOperation onOperation) {
75 | return FileName.IsMatch(fileName) && SheetName.IsMatch(sheetName) && OnOperation.HasFlag(onOperation);
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/seedtable.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29609.76
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "seedtable", "seedtable\seedtable.csproj", "{8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "seedtable-gui", "seedtable-gui\seedtable-gui.csproj", "{C4F0466D-88F8-4E40-AF57-325C47B7F93D}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "seedtable-test", "seedtable-test\seedtable-test.csproj", "{3E8A7E5F-5B32-40B7-BEC4-6DA114ED3E4A}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "seedtable-egui", "seedtable-egui\seedtable-egui.csproj", "{26B346FC-D406-4F9C-B57D-353A5007124A}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Debug|x86 = Debug|x86
18 | Release|Any CPU = Release|Any CPU
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Debug|x86.ActiveCfg = Debug|Any CPU
25 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Debug|x86.Build.0 = Debug|Any CPU
26 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Release|x86.ActiveCfg = Release|Any CPU
29 | {8BD2867D-75B8-4DA7-9E62-B23E994CD3A0}.Release|x86.Build.0 = Release|Any CPU
30 | {C4F0466D-88F8-4E40-AF57-325C47B7F93D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {C4F0466D-88F8-4E40-AF57-325C47B7F93D}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {C4F0466D-88F8-4E40-AF57-325C47B7F93D}.Debug|x86.ActiveCfg = Debug|Any CPU
33 | {C4F0466D-88F8-4E40-AF57-325C47B7F93D}.Debug|x86.Build.0 = Debug|Any CPU
34 | {C4F0466D-88F8-4E40-AF57-325C47B7F93D}.Release|Any CPU.ActiveCfg = Release|Any CPU
35 | {C4F0466D-88F8-4E40-AF57-325C47B7F93D}.Release|Any CPU.Build.0 = Release|Any CPU
36 | {C4F0466D-88F8-4E40-AF57-325C47B7F93D}.Release|x86.ActiveCfg = Release|Any CPU
37 | {C4F0466D-88F8-4E40-AF57-325C47B7F93D}.Release|x86.Build.0 = Release|Any CPU
38 | {3E8A7E5F-5B32-40B7-BEC4-6DA114ED3E4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {3E8A7E5F-5B32-40B7-BEC4-6DA114ED3E4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {3E8A7E5F-5B32-40B7-BEC4-6DA114ED3E4A}.Debug|x86.ActiveCfg = Debug|Any CPU
41 | {3E8A7E5F-5B32-40B7-BEC4-6DA114ED3E4A}.Debug|x86.Build.0 = Debug|Any CPU
42 | {3E8A7E5F-5B32-40B7-BEC4-6DA114ED3E4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
43 | {3E8A7E5F-5B32-40B7-BEC4-6DA114ED3E4A}.Release|Any CPU.Build.0 = Release|Any CPU
44 | {3E8A7E5F-5B32-40B7-BEC4-6DA114ED3E4A}.Release|x86.ActiveCfg = Release|Any CPU
45 | {3E8A7E5F-5B32-40B7-BEC4-6DA114ED3E4A}.Release|x86.Build.0 = Release|Any CPU
46 | {26B346FC-D406-4F9C-B57D-353A5007124A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47 | {26B346FC-D406-4F9C-B57D-353A5007124A}.Debug|Any CPU.Build.0 = Debug|Any CPU
48 | {26B346FC-D406-4F9C-B57D-353A5007124A}.Debug|x86.ActiveCfg = Debug|Any CPU
49 | {26B346FC-D406-4F9C-B57D-353A5007124A}.Debug|x86.Build.0 = Debug|Any CPU
50 | {26B346FC-D406-4F9C-B57D-353A5007124A}.Release|Any CPU.ActiveCfg = Release|Any CPU
51 | {26B346FC-D406-4F9C-B57D-353A5007124A}.Release|Any CPU.Build.0 = Release|Any CPU
52 | {26B346FC-D406-4F9C-B57D-353A5007124A}.Release|x86.ActiveCfg = Release|Any CPU
53 | {26B346FC-D406-4F9C-B57D-353A5007124A}.Release|x86.Build.0 = Release|Any CPU
54 | EndGlobalSection
55 | GlobalSection(SolutionProperties) = preSolution
56 | HideSolutionNode = FALSE
57 | EndGlobalSection
58 | GlobalSection(ExtensibilityGlobals) = postSolution
59 | SolutionGuid = {6092105F-8C94-4678-9FBC-278C91BB1DD8}
60 | EndGlobalSection
61 | GlobalSection(MonoDevelopProperties) = preSolution
62 | StartupItem = seedtable\seedtable.csproj
63 | EndGlobalSection
64 | EndGlobal
65 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2.1
2 |
3 | orbs:
4 | win: circleci/windows@2.2.0
5 | github-release: izumin5210/github-release@0.1.1
6 |
7 | workflows:
8 | version: 2
9 | build_and_test:
10 | jobs:
11 | - linux-test:
12 | filters:
13 | tags:
14 | only: /v.*/
15 | - linux-xm-build:
16 | filters:
17 | tags:
18 | only: /v.*/
19 | - linux-egui-build:
20 | filters:
21 | tags:
22 | only: /v.*/
23 | - github-release/create:
24 | requires:
25 | - linux-xm-build
26 | - linux-egui-build
27 | filters:
28 | branches:
29 | ignore: /.*/
30 | tags:
31 | only: /v.*/
32 | path: ./releases/
33 |
34 | jobs:
35 | windows-build:
36 | executor: win/default
37 | steps:
38 | - checkout
39 | - run:
40 | command: choco install dotnetcore-sdk --version 3.1.100 -y
41 | - run:
42 | command: nuget sources Enable -Name nuget.org
43 | - restore_cache:
44 | keys:
45 | - packages-cache-windows-{{ checksum "seedtable/seedtable.csproj" }}-{{ checksum "seedtable-gui/seedtable-gui.csproj" }}
46 | - run:
47 | command: dotnet restore
48 | - save_cache:
49 | paths:
50 | - C:\Users\circleci\.nuget\packages
51 | key: packages-cache-windows-{{ checksum "seedtable/seedtable.csproj" }}-{{ checksum "seedtable-gui/seedtable-gui.csproj" }}
52 | - run:
53 | command: dotnet test seedtable-test
54 | - run:
55 | command: .\publish.bat
56 | - run:
57 | command: $ProgressPreference = "SilentlyContinue"; .\releases.ps1
58 | - store_artifacts:
59 | path: .\releases
60 |
61 | linux-test:
62 | docker:
63 | - image: mcr.microsoft.com/dotnet/core/sdk:3.1-alpine
64 | steps:
65 | - checkout
66 | - restore_cache:
67 | keys:
68 | - packages-cache-linux-{{ checksum "seedtable/seedtable.csproj" }}-{{ checksum "seedtable-gui/seedtable-gui.csproj" }}
69 | - run:
70 | name: "Install project dependencies"
71 | command: dotnet restore seedtable-test
72 | - save_cache:
73 | paths:
74 | - ~/.nuget/packages
75 | key: packages-cache-linux-{{ checksum "seedtable/seedtable.csproj" }}-{{ checksum "seedtable-gui/seedtable-gui.csproj" }}
76 | - run:
77 | name: "Test the executable"
78 | command: dotnet test seedtable-test
79 |
80 | linux-xm-build:
81 | docker:
82 | - image: narazaka/dotnet-openmotif:latest
83 | steps:
84 | - checkout
85 | - run:
86 | command: git submodule update --init
87 | - run:
88 | command: dotnet restore seedtable-x11/XmSeedtable
89 | - run:
90 | command: sh publish-xm-linux.sh
91 | - run:
92 | command: sh releases-xm-linux.sh
93 | - store_artifacts:
94 | path: ./releases
95 | - persist_to_workspace:
96 | root: .
97 | paths:
98 | - ./releases/*
99 |
100 | linux-egui-build:
101 | docker:
102 | - image: narazaka/dotnet-node:latest
103 | steps:
104 | - checkout
105 | - run:
106 | command: dotnet restore seedtable-egui
107 | - run:
108 | command: dotnet tool install ElectronNET.CLI -g --version 8.31.1
109 | - run:
110 | command: npm install -g electron-builder
111 | - run:
112 | command: sh publish-egui-linux.sh
113 | - run:
114 | command: sh releases-egui-linux.sh
115 | - store_artifacts:
116 | path: ./releases
117 | - persist_to_workspace:
118 | root: .
119 | paths:
120 | - ./releases/*
121 |
122 | osx-test:
123 | macos:
124 | xcode: "11.0"
125 | steps:
126 | - checkout
127 | - run: brew cask install dotnet-sdk
128 | - restore_cache:
129 | keys:
130 | - packages-cache-osx-{{ checksum "seedtable/seedtable.csproj" }}-{{ checksum "seedtable-gui/seedtable-gui.csproj" }}
131 | - run:
132 | name: "Install project dependencies"
133 | command: dotnet restore seedtable-test
134 | - save_cache:
135 | paths:
136 | - ~/.nuget/packages
137 | key: packages-cache-osx-{{ checksum "seedtable/seedtable.csproj" }}-{{ checksum "seedtable-gui/seedtable-gui.csproj" }}
138 | - run:
139 | name: "Test the executable"
140 | command: dotnet test seedtable-test
141 |
--------------------------------------------------------------------------------
/seedtable/DataDictionaryList.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Collections.Generic;
3 |
4 | namespace SeedTable {
5 | /** レコードDictionaryのリスト */
6 | public class DataDictionaryList {
7 | /** [{id: 1, name: "foo"}, ...] */
8 | public IEnumerable> Table { get; private set; }
9 | /** key column name (ex. "id") */
10 | public string KeyColumnName { get; private set; }
11 |
12 | /**
13 | * コンストラクタ
14 | *
15 | * 渡されたレコードリストからidが空白であるものを省き、値が空白であるデータをnullに変換して受け取る
16 | *
17 | * @param table [{id: 1, name: "foo"}, ...]的なデータ
18 | */
19 | public DataDictionaryList(IEnumerable> table, string keyColumnName) {
20 | KeyColumnName = keyColumnName;
21 | Table = table
22 | .Where(rowData => rowData.ContainsKey(KeyColumnName) && rowData[KeyColumnName] != null && (rowData[KeyColumnName].ToString()).Length != 0)
23 | .Select(rowData => rowData.ToDictionary(pair => pair.Key, pair => pair.Value is string && ((string) pair.Value) == "" ? null : pair.Value));
24 | }
25 |
26 | /**
27 | * {data1: {id: 1, name: "foo"}, ...}形式で返す
28 | */
29 | public Dictionary> ToDictionaryDictionary() {
30 | var dic = new Dictionary>();
31 | foreach (var row in Table) {
32 | dic["data" + row[KeyColumnName]] = row;
33 | }
34 | return dic;
35 | }
36 |
37 | /**
38 | * {"1": {id: 1, name: "foo"}, ...}形式で返す
39 | */
40 | public Dictionary> IndexById() {
41 | var dic = new Dictionary>();
42 | foreach (var row in Table) {
43 | dic[row[KeyColumnName].ToString()] = row;
44 | }
45 | return dic;
46 | }
47 |
48 | /**
49 | * カットされたIDグループごとのレコードリスト
50 | *
51 | * {"data101": [{id: 10101, name: "foo"}], ...}形式で返す
52 | */
53 | public Dictionary>> ToSeparated(int preCut = 0, int postCut = 0, string subdivideFilename = null) {
54 | var dic = new Dictionary>>();
55 | foreach (var row in Table) {
56 | var id = row[KeyColumnName].ToString();
57 | var subdivideId = SubdivideId(id, preCut, postCut);
58 | if (subdivideId == null) continue; // idが空なものはスキップ
59 | var cutIdKey = CutIdKey(subdivideId, subdivideFilename);
60 | if (!dic.ContainsKey(cutIdKey)) dic[cutIdKey] = new List>();
61 | dic[cutIdKey].Add(row);
62 | }
63 | return dic;
64 | }
65 |
66 | /**
67 | * カットされたIDグループごとのレコードリスト
68 | *
69 | * {"data101": {data10101: {id: 10101, name: "foo"}}, ...}形式で返す
70 | */
71 | public Dictionary>> ToSeparatedDictionaryDictionary(int preCut = 0, int postCut = 0, string subdivideFilename = null) {
72 | var dic = new Dictionary>>();
73 | foreach (var row in Table) {
74 | var id = row[KeyColumnName].ToString();
75 | var subdivideId = SubdivideId(id, preCut, postCut);
76 | if (subdivideId == null) continue; // idが空なものはスキップ
77 | var cutIdKey = CutIdKey(subdivideId, subdivideFilename);
78 | if (!dic.ContainsKey(cutIdKey)) dic[cutIdKey] = new Dictionary>();
79 | dic[cutIdKey]["data" + id] = row;
80 | }
81 | return dic;
82 | }
83 |
84 | private string SubdivideId(string id, int preCut = 0, int postCut = 0) {
85 | var idLength = id.Length;
86 | if (idLength == 0) return null; // idが空なものはスキップ
87 | var useIdLength = idLength - preCut - postCut;
88 | return id.Substring(preCut > idLength ? idLength : preCut, useIdLength < 0 ? 0 : useIdLength);
89 | }
90 |
91 | private string CutIdKey(string subdivideId, string subdivideFilename = null) {
92 | if (subdivideFilename == null) {
93 | return "data" + subdivideId;
94 | } else {
95 | return string.Format(subdivideFilename, int.Parse(subdivideId));
96 | }
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/seedtable-test/SubdivideTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.IO;
7 | using Xunit;
8 |
9 | using SeedTable;
10 |
11 | namespace seedtable_test {
12 | public class SubdivideTest : FromToTestBase {
13 | private const string SheetName = "foo_bars";
14 | private readonly IEnumerable> AllData;
15 |
16 | public SubdivideTest() {
17 | var options = BuildOptions();
18 | Prepare(options);
19 | var data = GetYamlData(Path.Combine(options.output, $"{SheetName}.yml"));
20 | AllData = data.OrderBy(record => record["id"]);
21 | }
22 |
23 | protected FromOptions BuildOptions(int? preCut = null, int? postCut = null) {
24 | var options = base.BuildFromOptions();
25 | options.only = new string[] { SheetName };
26 | var preCutStr = preCut == null ? "" : $"{preCut}:";
27 | var postCutStr = postCut == null ? "" : $":{postCut}";
28 | options.subdivide = new string[] { $"{preCutStr}{SheetName}{postCutStr}" };
29 | return options;
30 | }
31 |
32 | private static readonly int[] AllIds = new int[] {
33 | 10001,
34 | 10008,
35 | 10015,
36 | 10022,
37 | 10029,
38 | 10036,
39 | 10043,
40 | 10050,
41 | 10057,
42 | 10064,
43 | 10071,
44 | 10078,
45 | 10085,
46 | 10092,
47 | 10099,
48 | 10106,
49 | 10113,
50 | 10120,
51 | 10127,
52 | 10134,
53 | 10141,
54 | 10148,
55 | 10155,
56 | 10162,
57 | 10169,
58 | 10176,
59 | 10183,
60 | 10190,
61 | 10197,
62 | 10204,
63 | 10211,
64 | 10218,
65 | };
66 |
67 | private static readonly IEnumerable AllIdsStr = AllIds.Select(id => id.ToString());
68 |
69 | public static IEnumerable Examples() {
70 | yield return new object[] { null, 0, AllIdsStr };
71 | yield return new object[] { 0, null, AllIdsStr };
72 | yield return new object[] { 0, 0, AllIdsStr };
73 | yield return new object[] { null, 3, new string[] { "10" } };
74 | yield return new object[] { null, 5, new string[] { null } };
75 | yield return new object[] { null, 9, new string[] { null } };
76 | yield return new object[] { 1, null, AllIdsStr.Select(id => id.Substring(1)) };
77 | yield return new object[] { 5, null, new string[] { null } };
78 | yield return new object[] { 6, null, new string[] { null } };
79 | yield return new object[] { 0, 3, new string[] { "10" } };
80 | yield return new object[] { 1, 0, AllIdsStr.Select(id => id.Substring(1)) };
81 | yield return new object[] { 1, 2, new string[] { "00", "01", "02" } };
82 | yield return new object[] { 2, 2, new string[] { "0", "1", "2" } };
83 | yield return new object[] { 3, 2, new string[] { null } };
84 | yield return new object[] { 3, 3, new string[] { null } };
85 | }
86 |
87 | private readonly Func IdComparator = id => id == null ? 0 : int.Parse(id);
88 |
89 | [Theory]
90 | [MemberData(nameof(Examples))]
91 | private void Check(int? preCut, int? postCut, IEnumerable separatedIds) {
92 | var options = BuildOptions(preCut, postCut);
93 | Prepare(options);
94 |
95 | var destPath = Path.Combine(options.output, SheetName);
96 | Assert.True(Directory.Exists(destPath));
97 | var separatedAllData = new List>>();
98 | var separatedAllIds = new List();
99 | foreach (var filePath in Directory.GetFiles(destPath)) {
100 | var separatedId = Path.GetFileNameWithoutExtension(filePath).Substring(4);
101 | separatedAllIds.Add(separatedId.Length == 0 ? null : separatedId);
102 | separatedAllData.Add(GetYamlData(filePath));
103 | }
104 | var combinedAllData = separatedAllData.SelectMany(data => data).OrderBy(record => record["id"]);
105 | Assert.Equal(AllData, combinedAllData);
106 | Assert.Equal(separatedAllIds.OrderBy(IdComparator), separatedIds.OrderBy(IdComparator));
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/seedtable-gui/YamlToExcelDialog.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace seedtable_gui {
2 | partial class YamlToExcelDialog {
3 | ///
4 | /// Required designer variable.
5 | ///
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | ///
9 | /// Clean up any resources being used.
10 | ///
11 | /// true if managed resources should be disposed; otherwise, false.
12 | protected override void Dispose(bool disposing) {
13 | if (disposing && (components != null)) {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | ///
22 | /// Required method for Designer support - do not modify
23 | /// the contents of this method with the code editor.
24 | ///
25 | private void InitializeComponent() {
26 | this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
27 | this.okButton = new System.Windows.Forms.Button();
28 | this.infoTextBox = new System.Windows.Forms.TextBox();
29 | this.seedToExcelBackgroundWorker = new System.ComponentModel.BackgroundWorker();
30 | this.tableLayoutPanel.SuspendLayout();
31 | this.SuspendLayout();
32 | //
33 | // tableLayoutPanel
34 | //
35 | this.tableLayoutPanel.ColumnCount = 1;
36 | this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
37 | this.tableLayoutPanel.Controls.Add(this.okButton, 0, 1);
38 | this.tableLayoutPanel.Controls.Add(this.infoTextBox, 0, 0);
39 | this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
40 | this.tableLayoutPanel.Location = new System.Drawing.Point(0, 0);
41 | this.tableLayoutPanel.Name = "tableLayoutPanel";
42 | this.tableLayoutPanel.RowCount = 2;
43 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
44 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30F));
45 | this.tableLayoutPanel.Size = new System.Drawing.Size(284, 261);
46 | this.tableLayoutPanel.TabIndex = 1;
47 | //
48 | // okButton
49 | //
50 | this.okButton.Anchor = System.Windows.Forms.AnchorStyles.None;
51 | this.okButton.Enabled = false;
52 | this.okButton.Location = new System.Drawing.Point(104, 234);
53 | this.okButton.Name = "okButton";
54 | this.okButton.Size = new System.Drawing.Size(75, 23);
55 | this.okButton.TabIndex = 0;
56 | this.okButton.Text = "OK";
57 | this.okButton.UseVisualStyleBackColor = true;
58 | this.okButton.Click += new System.EventHandler(this.okButton_Click);
59 | //
60 | // infoTextBox
61 | //
62 | this.infoTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
63 | this.infoTextBox.Location = new System.Drawing.Point(3, 3);
64 | this.infoTextBox.Multiline = true;
65 | this.infoTextBox.Name = "infoTextBox";
66 | this.infoTextBox.ReadOnly = true;
67 | this.infoTextBox.Size = new System.Drawing.Size(278, 225);
68 | this.infoTextBox.TabIndex = 1;
69 | //
70 | // seedToExcelBackgroundWorker
71 | //
72 | this.seedToExcelBackgroundWorker.WorkerReportsProgress = true;
73 | this.seedToExcelBackgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.seedToExcelBackgroundWorker_DoWork);
74 | this.seedToExcelBackgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.seedToExcelBackgroundWorker_ProgressChanged);
75 | this.seedToExcelBackgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.seedToExcelBackgroundWorker_RunWorkerCompleted);
76 | //
77 | // YamlToExcelDialog
78 | //
79 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
81 | this.ClientSize = new System.Drawing.Size(284, 261);
82 | this.Controls.Add(this.tableLayoutPanel);
83 | this.Name = "YamlToExcelDialog";
84 | this.Text = "YamlToExcelDialog";
85 | this.Shown += new System.EventHandler(this.YamlToExcelDialog_Shown);
86 | this.tableLayoutPanel.ResumeLayout(false);
87 | this.tableLayoutPanel.PerformLayout();
88 | this.ResumeLayout(false);
89 |
90 | }
91 |
92 | #endregion
93 |
94 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
95 | private System.Windows.Forms.Button okButton;
96 | private System.Windows.Forms.TextBox infoTextBox;
97 | private System.ComponentModel.BackgroundWorker seedToExcelBackgroundWorker;
98 | }
99 | }
--------------------------------------------------------------------------------
/seedtable-gui/SettingDialog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Globalization;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using System.Windows.Forms;
11 |
12 | using SeedTable;
13 |
14 | namespace seedtable_gui {
15 | public partial class SettingDialog : BaseForm {
16 | public SettingDialog(BasicOptions options, bool changeable = true) : base() {
17 | InitializeComponent();
18 | foreach (Control controll in Controls) {
19 | controll.Enabled = changeable;
20 | }
21 |
22 | var toOptionsStringListDataSource = new CommonOptionsStringListDataSource(options);
23 | subdivideTextBox.DataBindings.Add("Text", toOptionsStringListDataSource, "subdivide", true, DataSourceUpdateMode.OnPropertyChanged);
24 | onlyTextBox.DataBindings.Add("Text", toOptionsStringListDataSource, "only", true, DataSourceUpdateMode.OnPropertyChanged);
25 | ignoreTextBox.DataBindings.Add("Text", toOptionsStringListDataSource, "ignore", true, DataSourceUpdateMode.OnPropertyChanged);
26 | primaryTextBox.DataBindings.Add("Text", toOptionsStringListDataSource, "primary", true, DataSourceUpdateMode.OnPropertyChanged);
27 | mappingTextBox.DataBindings.Add("Text", toOptionsStringListDataSource, "mapping", true, DataSourceUpdateMode.OnPropertyChanged);
28 | aliasTextBox.DataBindings.Add("Text", toOptionsStringListDataSource, "alias", true, DataSourceUpdateMode.OnPropertyChanged);
29 | ignoreColumnsTextBox.DataBindings.Add("Text", toOptionsStringListDataSource, "ignoreColumns", true, DataSourceUpdateMode.OnPropertyChanged);
30 | yamlColumnsTextBox.DataBindings.Add("Text", toOptionsStringListDataSource, "yamlColumns", true, DataSourceUpdateMode.OnPropertyChanged);
31 |
32 | engineComboBox.DataSource = Enum.GetValues(typeof(BasicOptions.Engine));
33 | formatComboBox.DataSource = Enum.GetValues(typeof(SeedYamlFormat));
34 | basicOptionsBindingSource.DataSource = options;
35 | }
36 | }
37 |
38 | class CommonOptionsStringListDataSource {
39 | BasicOptions Options;
40 |
41 | public CommonOptionsStringListDataSource(BasicOptions options) {
42 | Options = options;
43 | }
44 |
45 | [TypeConverter(typeof(StringListToMultiLineStringConverter))]
46 | public IEnumerable subdivide {
47 | get { return Options.subdivide; }
48 | set { Options.subdivide = value; }
49 | }
50 |
51 | [TypeConverter(typeof(StringListToMultiLineStringConverter))]
52 | public IEnumerable only {
53 | get { return Options.only; }
54 | set { Options.only = value; }
55 | }
56 |
57 | [TypeConverter(typeof(StringListToMultiLineStringConverter))]
58 | public IEnumerable ignore {
59 | get { return Options.ignore; }
60 | set { Options.ignore = value; }
61 | }
62 |
63 | [TypeConverter(typeof(StringListToMultiLineStringConverter))]
64 | public IEnumerable primary {
65 | get { return Options.primary; }
66 | set { Options.primary = value; }
67 | }
68 |
69 | [TypeConverter(typeof(StringListToMultiLineStringConverter))]
70 | public IEnumerable mapping {
71 | get { return Options.mapping; }
72 | set { Options.mapping = value; }
73 | }
74 |
75 | [TypeConverter(typeof(StringListToMultiLineStringConverter))]
76 | public IEnumerable alias {
77 | get { return Options.alias; }
78 | set { Options.alias = value; }
79 | }
80 |
81 | [TypeConverter(typeof(StringListToMultiLineStringConverter))]
82 | public IEnumerable ignoreColumns {
83 | get { return Options.ignoreColumns; }
84 | set { Options.ignoreColumns = value; }
85 | }
86 |
87 | [TypeConverter(typeof(StringListToMultiLineStringConverter))]
88 | public IEnumerable yamlColumns {
89 | get { return Options.yamlColumns; }
90 | set { Options.yamlColumns = value; }
91 | }
92 | }
93 |
94 | class StringListToMultiLineStringConverter : TypeConverter {
95 | public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
96 | return sourceType == typeof(string);
97 | }
98 |
99 | public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
100 | return ((string)value).Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
101 | }
102 |
103 | public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
104 | return destinationType == typeof(string);
105 | }
106 |
107 | public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
108 | return string.Join(Environment.NewLine, (IEnumerable)value);
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/seedtable-gui/ExcelToYamlDialog.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace seedtable_gui {
2 | partial class ExcelToYamlDialog {
3 | ///
4 | /// Required designer variable.
5 | ///
6 | private System.ComponentModel.IContainer components = null;
7 |
8 | ///
9 | /// Clean up any resources being used.
10 | ///
11 | /// true if managed resources should be disposed; otherwise, false.
12 | protected override void Dispose(bool disposing) {
13 | if (disposing && (components != null)) {
14 | components.Dispose();
15 | }
16 | base.Dispose(disposing);
17 | }
18 |
19 | #region Windows Form Designer generated code
20 |
21 | ///
22 | /// Required method for Designer support - do not modify
23 | /// the contents of this method with the code editor.
24 | ///
25 | private void InitializeComponent() {
26 | this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
27 | this.okButton = new System.Windows.Forms.Button();
28 | this.infoTextBox = new System.Windows.Forms.TextBox();
29 | this.excelToSeedBackgroundWorker = new System.ComponentModel.BackgroundWorker();
30 | this.tableLayoutPanel.SuspendLayout();
31 | this.SuspendLayout();
32 | //
33 | // tableLayoutPanel
34 | //
35 | this.tableLayoutPanel.ColumnCount = 1;
36 | this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
37 | this.tableLayoutPanel.Controls.Add(this.okButton, 0, 1);
38 | this.tableLayoutPanel.Controls.Add(this.infoTextBox, 0, 0);
39 | this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
40 | this.tableLayoutPanel.Location = new System.Drawing.Point(0, 0);
41 | this.tableLayoutPanel.Name = "tableLayoutPanel";
42 | this.tableLayoutPanel.RowCount = 2;
43 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
44 | this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 30F));
45 | this.tableLayoutPanel.Size = new System.Drawing.Size(284, 261);
46 | this.tableLayoutPanel.TabIndex = 0;
47 | //
48 | // okButton
49 | //
50 | this.okButton.Anchor = System.Windows.Forms.AnchorStyles.None;
51 | this.okButton.Enabled = false;
52 | this.okButton.Location = new System.Drawing.Point(104, 234);
53 | this.okButton.Name = "okButton";
54 | this.okButton.Size = new System.Drawing.Size(75, 23);
55 | this.okButton.TabIndex = 0;
56 | this.okButton.Text = "OK";
57 | this.okButton.UseVisualStyleBackColor = true;
58 | this.okButton.Click += new System.EventHandler(this.okButton_Click);
59 | //
60 | // infoTextBox
61 | //
62 | this.infoTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
63 | this.infoTextBox.Location = new System.Drawing.Point(3, 3);
64 | this.infoTextBox.Multiline = true;
65 | this.infoTextBox.Name = "infoTextBox";
66 | this.infoTextBox.ReadOnly = true;
67 | this.infoTextBox.Size = new System.Drawing.Size(278, 225);
68 | this.infoTextBox.TabIndex = 1;
69 | //
70 | // excelToSeedBackgroundWorker
71 | //
72 | this.excelToSeedBackgroundWorker.WorkerReportsProgress = true;
73 | this.excelToSeedBackgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.excelToSeedBackgroundWorker_DoWork);
74 | this.excelToSeedBackgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.excelToSeedBackgroundWorker_ProgressChanged);
75 | this.excelToSeedBackgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.excelToSeedBackgroundWorker_RunWorkerCompleted);
76 | //
77 | // ExcelToYamlDialog
78 | //
79 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
80 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
81 | this.ClientSize = new System.Drawing.Size(284, 261);
82 | this.ControlBox = false;
83 | this.Controls.Add(this.tableLayoutPanel);
84 | this.Name = "ExcelToYamlDialog";
85 | this.ShowInTaskbar = false;
86 | this.Text = "xlsx → yml";
87 | this.Shown += new System.EventHandler(this.ExcelToYamlDialog_Shown);
88 | this.tableLayoutPanel.ResumeLayout(false);
89 | this.tableLayoutPanel.PerformLayout();
90 | this.ResumeLayout(false);
91 |
92 | }
93 |
94 | #endregion
95 |
96 | private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
97 | private System.Windows.Forms.Button okButton;
98 | private System.Windows.Forms.TextBox infoTextBox;
99 | private System.ComponentModel.BackgroundWorker excelToSeedBackgroundWorker;
100 | }
101 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 |
84 | # Visual Studio profiler
85 | *.psess
86 | *.vsp
87 | *.vspx
88 | *.sap
89 |
90 | # TFS 2012 Local Workspace
91 | $tf/
92 |
93 | # Guidance Automation Toolkit
94 | *.gpState
95 |
96 | # ReSharper is a .NET coding add-in
97 | _ReSharper*/
98 | *.[Rr]e[Ss]harper
99 | *.DotSettings.user
100 |
101 | # JustCode is a .NET coding add-in
102 | .JustCode
103 |
104 | # TeamCity is a build add-in
105 | _TeamCity*
106 |
107 | # DotCover is a Code Coverage Tool
108 | *.dotCover
109 |
110 | # NCrunch
111 | _NCrunch_*
112 | .*crunch*.local.xml
113 | nCrunchTemp_*
114 |
115 | # MightyMoose
116 | *.mm.*
117 | AutoTest.Net/
118 |
119 | # Web workbench (sass)
120 | .sass-cache/
121 |
122 | # Installshield output folder
123 | [Ee]xpress/
124 |
125 | # DocProject is a documentation generator add-in
126 | DocProject/buildhelp/
127 | DocProject/Help/*.HxT
128 | DocProject/Help/*.HxC
129 | DocProject/Help/*.hhc
130 | DocProject/Help/*.hhk
131 | DocProject/Help/*.hhp
132 | DocProject/Help/Html2
133 | DocProject/Help/html
134 |
135 | # Click-Once directory
136 | publish/
137 |
138 | # Publish Web Output
139 | *.[Pp]ublish.xml
140 | *.azurePubxml
141 | # TODO: Comment the next line if you want to checkin your web deploy settings
142 | # but database connection strings (with potential passwords) will be unencrypted
143 | # *.pubxml
144 | *.publishproj
145 |
146 | # NuGet Packages
147 | *.nupkg
148 | # The packages folder can be ignored because of Package Restore
149 | **/packages/*
150 | # except build/, which is used as an MSBuild target.
151 | !**/packages/build/
152 | # Uncomment if necessary however generally it will be regenerated when needed
153 | #!**/packages/repositories.config
154 | # NuGet v3's project.json files produces more ignoreable files
155 | *.nuget.props
156 | *.nuget.targets
157 |
158 | # Microsoft Azure Build Output
159 | csx/
160 | *.build.csdef
161 |
162 | # Microsoft Azure Emulator
163 | ecf/
164 | rcf/
165 |
166 | # Microsoft Azure ApplicationInsights config file
167 | ApplicationInsights.config
168 |
169 | # Windows Store app package directories and files
170 | AppPackages/
171 | BundleArtifacts/
172 | Package.StoreAssociation.xml
173 | _pkginfo.txt
174 |
175 | # Visual Studio cache files
176 | # files ending in .cache can be ignored
177 | *.[Cc]ache
178 | # but keep track of directories ending in .cache
179 | !*.[Cc]ache/
180 |
181 | # Others
182 | ClientBin/
183 | ~$*
184 | *~
185 | *.dbmdl
186 | *.dbproj.schemaview
187 | *.pfx
188 | *.publishsettings
189 | node_modules/
190 | orleans.codegen.cs
191 |
192 | # Since there are multiple workflows, uncomment next line to ignore bower_components
193 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
194 | #bower_components/
195 |
196 | # RIA/Silverlight projects
197 | Generated_Code/
198 |
199 | # Backup & report files from converting an old project file
200 | # to a newer Visual Studio version. Backup files are not needed,
201 | # because we have git ;-)
202 | _UpgradeReport_Files/
203 | Backup*/
204 | UpgradeLog*.XML
205 | UpgradeLog*.htm
206 |
207 | # SQL Server files
208 | *.mdf
209 | *.ldf
210 |
211 | # Business Intelligence projects
212 | *.rdl.data
213 | *.bim.layout
214 | *.bim_*.settings
215 |
216 | # Microsoft Fakes
217 | FakesAssemblies/
218 |
219 | # GhostDoc plugin setting file
220 | *.GhostDoc.xml
221 |
222 | # Node.js Tools for Visual Studio
223 | .ntvs_analysis.dat
224 |
225 | # Visual Studio 6 build log
226 | *.plg
227 |
228 | # Visual Studio 6 workspace options file
229 | *.opt
230 |
231 | # Visual Studio LightSwitch build output
232 | **/*.HTMLClient/GeneratedArtifacts
233 | **/*.DesktopClient/GeneratedArtifacts
234 | **/*.DesktopClient/ModelManifest.xml
235 | **/*.Server/GeneratedArtifacts
236 | **/*.Server/ModelManifest.xml
237 | _Pvt_Extensions
238 |
239 | # Paket dependency manager
240 | .paket/paket.exe
241 |
242 | # FAKE - F# Make
243 | .fake/
244 |
245 | # JetBrains Rider
246 | .idea/
247 | *.sln.iml
248 |
249 | /releases
250 |
--------------------------------------------------------------------------------
/seedtable-gui/Form1.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/seedtable/ClosedXML.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using ClosedXML.Excel;
5 |
6 | namespace SeedTable {
7 | namespace ClosedXML {
8 | class ExcelData : IExcelData {
9 | XLWorkbook Workbook;
10 |
11 | public static ExcelData FromFile(string file) => new ExcelData(new XLWorkbook(file));
12 |
13 | public ExcelData(XLWorkbook workbook) {
14 | Workbook = workbook;
15 | }
16 |
17 | public IEnumerable SheetNames {
18 | get { return Workbook.Worksheets.Select(worksheet => worksheet.Name); }
19 | }
20 |
21 | public SeedTableBase GetSeedTable(string sheetName, int columnNamesRowIndex = 2, int dataStartRowIndex = 3, IEnumerable ignoreColumnNames = null, string keyColumnName = "id", string versionColumnName = null) {
22 | IXLWorksheet worksheet;
23 | try {
24 | worksheet = Workbook.Worksheet(sheetName);
25 | } catch (Exception exception) {
26 | throw new SheetNotFoundException($"sheet [{sheetName}] not found", exception);
27 | }
28 | return new SeedTable(worksheet, columnNamesRowIndex, dataStartRowIndex, ignoreColumnNames, keyColumnName, versionColumnName);
29 | }
30 |
31 | public void Save() => Workbook.Save();
32 |
33 | public void SaveAs(string file) => Workbook.SaveAs(file);
34 |
35 | bool disposed = false;
36 |
37 | ~ExcelData() {
38 | this.Dispose(false);
39 | }
40 |
41 | public void Dispose() {
42 | this.Dispose(true);
43 | GC.SuppressFinalize(this);
44 | }
45 |
46 | protected virtual void Dispose(bool isDisposing) {
47 | if (disposed) return;
48 | if (isDisposing) Workbook.Dispose();
49 | disposed = true;
50 | }
51 | }
52 |
53 | class SeedTable : SeedTableBase {
54 | public IXLWorksheet Worksheet { get; private set; }
55 |
56 | public List Columns { get; } = new List();
57 | public int VersionColumnIndex { get; private set; }
58 | public int IdColumnIndex { get; private set; }
59 |
60 | public SeedTable(IXLWorksheet worksheet, int columnNamesRowIndex = 2, int dataStartRowIndex = 3, IEnumerable ignoreColumnNames = null, string keyColumnName = "id", string versionColumnName = null) : base(columnNamesRowIndex, dataStartRowIndex, ignoreColumnNames, keyColumnName, versionColumnName) {
61 | Worksheet = worksheet;
62 |
63 | GetColumns();
64 | }
65 |
66 | void GetColumns() {
67 | foreach (var cell in Worksheet.Row(ColumnNamesRowIndex).Cells()) {
68 | var value = cell.GetValue();
69 | if (value == null || value.Length == 0) continue;
70 | if (IgnoreColumnNames.Contains(value)) continue;
71 | if (VersionColumnName == value) {
72 | VersionColumnIndex = cell.Address.ColumnNumber;
73 | } else {
74 | var columnIndex = cell.Address.ColumnNumber;
75 | if (KeyColumnName == value) IdColumnIndex = columnIndex;
76 | Columns.Add(new SeedTableColumn(value, columnIndex));
77 | }
78 | }
79 | CheckColumns();
80 | }
81 |
82 | void CheckColumns() {
83 | if (IdColumnIndex == 0) Errors.Add(new NoIdColumnException($"key column [{KeyColumnName}] not found [{SheetName}]"));
84 | var columnNames = new HashSet();
85 | foreach(var column in Columns) {
86 | var columnName = column.Name;
87 | if (columnNames.Contains(columnName)) Errors.Add(new DuplicateColumnNameException($"Duplicate column name [{columnName}] found in sheet [{SheetName}]"));
88 | columnNames.Add(columnName);
89 | }
90 | }
91 |
92 | public override string SheetName { get { return Worksheet.Name; } }
93 |
94 | public override void DataToExcel(DataDictionaryList data, bool delete = false) {
95 | var indexedData = data.IndexById();
96 | var ids = new HashSet(indexedData.Keys);
97 | var restIds = new HashSet(indexedData.Keys);
98 | foreach (var row in Worksheet.Rows().Skip(DataStartRowIndex - 1)) {
99 | var id = row.Cell(IdColumnIndex).GetValue();
100 | if (ids.Contains(id)) {
101 | var rowData = indexedData[id];
102 | Columns.ForEach(column => {
103 | var cell = row.Cell(column.Index);
104 | var value = rowData[column.Name];
105 | if (!cell.HasFormula) cell.SetValue(value != null ? Convert.ToString(value) : "");
106 | });
107 | restIds.Remove(id);
108 | }
109 | };
110 | }
111 |
112 | public override DataDictionaryList ExcelToData(string requireVersion = "") {
113 | var table = Worksheet.Rows().Skip(DataStartRowIndex - 1).Select(row => this.GetRowValuesDictionary(row));
114 | return new DataDictionaryList(table, KeyColumnName);
115 | }
116 |
117 | Dictionary GetRowValuesDictionary(IXLRow row) => Columns.ToDictionary(column => column.Name, column => (row.Cell(column.Index).Value));
118 | }
119 |
120 | class SeedTableColumn {
121 | public string Name { get; }
122 | public int Index { get; }
123 | public SeedTableColumn(string name, int index) {
124 | Name = name;
125 | Index = index;
126 | }
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/seedtable-gui/SettingDialog.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------
/seedtable-gui/ExcelToYamlDialog.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
--------------------------------------------------------------------------------