├── .gitignore ├── Download ├── Essential │ ├── NDP452-KB2901907-x86-x64-AllOS-ENU.exe │ └── vstor_redist.exe ├── ExportJson_1_1_0_28.zip ├── ExportJson_1_1_0_29.zip ├── ExportJson_1_1_0_30.zip ├── ExportJson_1_1_0_31.zip ├── ExportJson_1_1_0_32.zip ├── ExportJson_1_1_0_33.zip └── Run.bat ├── ExportJson-2015.sln ├── ExportJson-2017.sln ├── ExportJson.sln ├── ExportJson.v12.suo ├── ExportJson ├── ExportJson.Designer.cs ├── ExportJson.cs ├── ExportJson.resx ├── ExportJsonPlugin.csproj ├── ExportJsonPlugin.csproj.user ├── ExportJson_TemporaryKey.pfx ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Settings.cs ├── ThisAddIn.Designer.cs ├── ThisAddIn.Designer.xml ├── ThisAddIn.cs ├── UnityCS.cs ├── app.config ├── fastJSON.cs ├── lib │ └── dotNetFx45_Full_setup.exe └── res │ ├── ConfigLoadTemplate.cs │ ├── ConfigTemplate.cs │ ├── josn_icon.ico │ └── josn_icon.png └── README.md /.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 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | ExportJson/bin/* 214 | ExportJson/obj* 215 | ExportJson/bin/Debug/ExportJson.dll 216 | ExportJson/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache 217 | ExportJson/obj/Debug/ExportJson.dll 218 | -------------------------------------------------------------------------------- /Download/Essential/NDP452-KB2901907-x86-x64-AllOS-ENU.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/Download/Essential/NDP452-KB2901907-x86-x64-AllOS-ENU.exe -------------------------------------------------------------------------------- /Download/Essential/vstor_redist.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/Download/Essential/vstor_redist.exe -------------------------------------------------------------------------------- /Download/ExportJson_1_1_0_28.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/Download/ExportJson_1_1_0_28.zip -------------------------------------------------------------------------------- /Download/ExportJson_1_1_0_29.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/Download/ExportJson_1_1_0_29.zip -------------------------------------------------------------------------------- /Download/ExportJson_1_1_0_30.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/Download/ExportJson_1_1_0_30.zip -------------------------------------------------------------------------------- /Download/ExportJson_1_1_0_31.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/Download/ExportJson_1_1_0_31.zip -------------------------------------------------------------------------------- /Download/ExportJson_1_1_0_32.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/Download/ExportJson_1_1_0_32.zip -------------------------------------------------------------------------------- /Download/ExportJson_1_1_0_33.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/Download/ExportJson_1_1_0_33.zip -------------------------------------------------------------------------------- /Download/Run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | call .\\Essential\\vstor_redist.exe 3 | call setup.exe -------------------------------------------------------------------------------- /ExportJson-2015.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportJsonPlugin", "ExportJson\ExportJsonPlugin.csproj", "{1FD54CD9-CF79-438A-BA29-29F49C6EFAD1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1FD54CD9-CF79-438A-BA29-29F49C6EFAD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {1FD54CD9-CF79-438A-BA29-29F49C6EFAD1}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {1FD54CD9-CF79-438A-BA29-29F49C6EFAD1}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {1FD54CD9-CF79-438A-BA29-29F49C6EFAD1}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ExportJson-2017.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26403.7 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportJsonPlugin", "ExportJson\ExportJsonPlugin.csproj", "{1FD54CD9-CF79-438A-BA29-29F49C6EFAD1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1FD54CD9-CF79-438A-BA29-29F49C6EFAD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {1FD54CD9-CF79-438A-BA29-29F49C6EFAD1}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {1FD54CD9-CF79-438A-BA29-29F49C6EFAD1}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {1FD54CD9-CF79-438A-BA29-29F49C6EFAD1}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ExportJson.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExportJson", "ExportJson\ExportJson.csproj", "{C81577D8-84AD-40C1-9316-257B0CCCFB22}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {C81577D8-84AD-40C1-9316-257B0CCCFB22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {C81577D8-84AD-40C1-9316-257B0CCCFB22}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {C81577D8-84AD-40C1-9316-257B0CCCFB22}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {C81577D8-84AD-40C1-9316-257B0CCCFB22}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /ExportJson.v12.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/ExportJson.v12.suo -------------------------------------------------------------------------------- /ExportJson/ExportJson.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ExportJsonPlugin 2 | { 3 | partial class ExportJson : Microsoft.Office.Tools.Ribbon.RibbonBase 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | public ExportJson() 11 | : base(Globals.Factory.GetRibbonFactory()) 12 | { 13 | InitializeComponent(); 14 | } 15 | 16 | /// 17 | /// 清理所有正在使用的资源。 18 | /// 19 | /// 如果应释放托管资源,为 true;否则为 false。 20 | protected override void Dispose(bool disposing) 21 | { 22 | if (disposing && (components != null)) 23 | { 24 | components.Dispose(); 25 | } 26 | base.Dispose(disposing); 27 | } 28 | 29 | #region 组件设计器生成的代码 30 | 31 | /// 32 | /// 设计器支持所需的方法 - 不要修改 33 | /// 使用代码编辑器修改此方法的内容。 34 | /// 35 | private void InitializeComponent() 36 | { 37 | this.tab1 = this.Factory.CreateRibbonTab(); 38 | this.JsonGroup = this.Factory.CreateRibbonGroup(); 39 | this.typeExportJson = this.Factory.CreateRibbonButton(); 40 | this.normalExportJson = this.Factory.CreateRibbonButton(); 41 | this.tab1.SuspendLayout(); 42 | this.JsonGroup.SuspendLayout(); 43 | this.SuspendLayout(); 44 | // 45 | // tab1 46 | // 47 | this.tab1.ControlId.ControlIdType = Microsoft.Office.Tools.Ribbon.RibbonControlIdType.Office; 48 | this.tab1.Groups.Add(this.JsonGroup); 49 | this.tab1.Label = "TabAddIns"; 50 | this.tab1.Name = "tab1"; 51 | // 52 | // JsonGroup 53 | // 54 | this.JsonGroup.Items.Add(this.normalExportJson); 55 | this.JsonGroup.Items.Add(this.typeExportJson); 56 | this.JsonGroup.Name = "JsonGroup"; 57 | // 58 | // typeExportJson 59 | // 60 | this.typeExportJson.Label = "类型模式导出JSON文件"; 61 | this.typeExportJson.Name = "typeExportJson"; 62 | this.typeExportJson.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.ExportJsonOfType); 63 | // 64 | // normalExportJson 65 | // 66 | this.normalExportJson.Label = "导出JSON文件"; 67 | this.normalExportJson.Name = "normalExportJson"; 68 | this.normalExportJson.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.ExportJsonOfNormal); 69 | // 70 | // ExportJson 71 | // 72 | this.Name = "ExportJson"; 73 | this.RibbonType = "Microsoft.Excel.Workbook"; 74 | this.Tabs.Add(this.tab1); 75 | this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.ExportJson_Load); 76 | this.tab1.ResumeLayout(false); 77 | this.tab1.PerformLayout(); 78 | this.JsonGroup.ResumeLayout(false); 79 | this.JsonGroup.PerformLayout(); 80 | this.ResumeLayout(false); 81 | 82 | } 83 | 84 | #endregion 85 | 86 | internal Microsoft.Office.Tools.Ribbon.RibbonTab tab1; 87 | internal Microsoft.Office.Tools.Ribbon.RibbonGroup JsonGroup; 88 | internal Microsoft.Office.Tools.Ribbon.RibbonButton typeExportJson; 89 | internal Microsoft.Office.Tools.Ribbon.RibbonButton normalExportJson; 90 | } 91 | 92 | partial class ThisRibbonCollection 93 | { 94 | internal ExportJson ExportJson 95 | { 96 | get { return this.GetRibbon(); } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /ExportJson/ExportJson.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Office.Tools.Ribbon; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | using System.Windows.Forms; 8 | using Excel = Microsoft.Office.Interop.Excel; 9 | using fastJSON; 10 | using ExportJson.Properties; 11 | using System.Linq; 12 | 13 | namespace ExportJsonPlugin 14 | { 15 | public partial class ExportJson 16 | { 17 | private string WorkbookFullName 18 | { 19 | get 20 | { 21 | return Globals.ThisAddIn.Application.ActiveWorkbook.FullName; 22 | } 23 | } 24 | private void ExportJson_Load(object sender, RibbonUIEventArgs e) 25 | { 26 | } 27 | 28 | private void Save(string json) 29 | { 30 | try 31 | { 32 | JSON.Instance.Parse(json); 33 | } 34 | catch (System.Exception _ex) 35 | { 36 | MessageBox.Show("数据异常,请检查"); 37 | return; 38 | } 39 | // SaveFileDialog saveFileDialog = new SaveFileDialog(); 40 | // saveFileDialog.Filter = "json文件(*.json)|"; 41 | // string fileName = Path.GetFileNameWithoutExtension(Globals.ThisAddIn.Application.ActiveWorkbook.FullName); 42 | // string[] titles = fileName.Split('_'); 43 | // string name = titles[0]; 44 | // saveFileDialog.InitialDirectory = Path.GetDirectoryName(fileName); 45 | // saveFileDialog.FileName = name; 46 | // saveFileDialog.ShowDialog(); 47 | 48 | string fileName = Path.GetFileNameWithoutExtension(WorkbookFullName); 49 | string[] titles = fileName.Split('_'); 50 | string name = titles[0]; 51 | 52 | string path = Path.GetDirectoryName(WorkbookFullName) + Path.DirectorySeparatorChar + "Out" + Path.DirectorySeparatorChar + "Json"; 53 | if (!Directory.Exists(path)) 54 | { 55 | Directory.CreateDirectory(path); 56 | } 57 | 58 | string jsonFileName = ""; 59 | if (!fileName.EndsWith(".json")) 60 | { 61 | //jsonFileName = saveFileDialog.FileName + ".json"; 62 | jsonFileName = path + Path.DirectorySeparatorChar + name + ".json"; 63 | } 64 | 65 | if (jsonFileName.Contains(":")) 66 | { 67 | FileStream fs = new FileStream(jsonFileName, FileMode.CreateNew | FileMode.OpenOrCreate); 68 | StreamWriter sw = new StreamWriter(fs); 69 | sw.Write(json); 70 | sw.Close(); 71 | MessageBox.Show("导出完成"); 72 | } 73 | } 74 | 75 | /// 76 | /// 把所有数据导出 77 | /// 1.字段 78 | /// 2.数据 79 | /// 80 | /// 81 | /// 82 | private void ExportJsonOfNormal(object sender, RibbonControlEventArgs e) 83 | { 84 | Excel.Worksheet activeWorksheet = Globals.ThisAddIn.Application.ActiveSheet; 85 | if(activeWorksheet == null) 86 | { 87 | MessageBox.Show("请启动编辑模式"); 88 | return; 89 | } 90 | List _Keys = new List(); 91 | 92 | List keyRang = GetLine(activeWorksheet, 1); 93 | if (keyRang.Count == 0) 94 | { 95 | return; 96 | } 97 | foreach (string cell in keyRang) 98 | { 99 | _Keys.Add(cell); 100 | } 101 | if (_Keys.Count == 0) 102 | { 103 | return; 104 | } 105 | 106 | StringBuilder stringBuilder = new StringBuilder(); 107 | stringBuilder.Append("["); 108 | 109 | int keyCount = keyRang.Count; 110 | int index = 1; 111 | while (true) 112 | { 113 | List dataRang = GetLine(activeWorksheet, ++index); 114 | if (dataRang.Count == 0) 115 | { 116 | break; 117 | } 118 | stringBuilder.Append("{"); 119 | 120 | for (int i = 0; i < _Keys.Count; ++i) 121 | { 122 | stringBuilder.Append("\"" + _Keys[i] + "\":"); 123 | if (i < dataRang.Count) 124 | { 125 | StringBuilder v1 = new StringBuilder(dataRang[i]); 126 | //string v = dataRang[i].Text; 127 | string v = v1.ToString().TrimEnd(); 128 | bool isInteger = Regex.IsMatch(v, @"^[-]?[1-9]{1}\d*$|^[0]{1}$"); 129 | bool isDecimal = Regex.IsMatch(v, @"^(-?\d+)(\.\d+)?$"); 130 | if (isInteger) 131 | { 132 | stringBuilder.Append(Convert.ToInt64(v)); 133 | } 134 | else if (isDecimal) 135 | { 136 | stringBuilder.Append(Convert.ToDouble(v)); 137 | } 138 | else 139 | { 140 | //v = v.Replace('\r', ' '); 141 | v = v.Replace('\n', ' '); 142 | stringBuilder.Append("\"" + v + "\""); 143 | } 144 | } 145 | else 146 | { 147 | stringBuilder.Append(""); 148 | } 149 | if (i != _Keys.Count - 1) 150 | { 151 | stringBuilder.Append(","); 152 | } 153 | } 154 | stringBuilder.Append("},"); 155 | } 156 | stringBuilder.Remove(stringBuilder.Length - 1, 1); 157 | stringBuilder.Append("]"); 158 | string json = stringBuilder.ToString(); 159 | /* 160 | byte[] unicodeBuf = Encoding.Unicode.GetBytes(json); 161 | byte[] utfBuf = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, unicodeBuf); 162 | json = Encoding.UTF8.GetString(utfBuf); 163 | * */ 164 | //验证JSON 165 | /* 166 | string utfJson = GB2312ToUTF8(json); 167 | 168 | JsonData dataSrc = JsonMapper.ToObject(utfJson); 169 | int a = 0; 170 | */ 171 | 172 | this.Save(json); 173 | } 174 | 175 | 176 | //字段类型 177 | List typeRang = new List(); 178 | //字段名称 179 | List keyRang = new List(); 180 | 181 | /// 182 | /// 根据类型导出数据 183 | /// 1.描述 184 | /// 2.类型 I->int F->float S->String B->bool 185 | /// 3.字段 186 | /// 4.数据 一级分隔符| 二级分隔符 _ 187 | /// 188 | /// 189 | /// 190 | private void ExportJsonOfType(object sender, RibbonControlEventArgs e) 191 | { 192 | typeRang.Clear(); 193 | keyRang.Clear(); 194 | 195 | Excel.Worksheet activeWorksheet = Globals.ThisAddIn.Application.ActiveSheet; 196 | string[] fileName = activeWorksheet.Application.Caption.Split('.'); 197 | 198 | List Keys = new List(); 199 | 200 | List Des = new List(); 201 | Des = GetLine(activeWorksheet, 1); 202 | 203 | keyRang = GetLine(activeWorksheet, 3); 204 | 205 | typeRang = GetLine(activeWorksheet, 2); 206 | 207 | 208 | 209 | if (typeRang.Count != keyRang.Count || typeRang.Count == 0 || keyRang.Count == 0) 210 | { 211 | MessageBox.Show("字段和类型个数不匹配"); 212 | return; 213 | } 214 | Dictionary _FieldsDic = new Dictionary(); 215 | for (int i = 0; i < keyRang.Count; ++i) 216 | { 217 | string cell = keyRang[i]; 218 | _FieldsDic.Add(cell, typeRang[i]); 219 | Keys.Add(cell); 220 | } 221 | 222 | if (_FieldsDic.Count == 0) 223 | { 224 | return; 225 | } 226 | 227 | StringBuilder stringBuilder = new StringBuilder(); 228 | stringBuilder.Append("["); 229 | int index = 3; 230 | while (true) 231 | { 232 | List dataRang = GetLine(activeWorksheet, ++index,false); 233 | if (dataRang.Count == 0) 234 | { 235 | break; 236 | } 237 | 238 | stringBuilder.Append("{"); 239 | 240 | for (int i = 0; i < Keys.Count; ++i) 241 | { 242 | stringBuilder.Append("\"" + ((string)keyRang[i]).Trim() + "\":"); 243 | string fieldType = ((string)typeRang[i]).Trim(); 244 | if (i < dataRang.Count) 245 | { 246 | StringBuilder v1 = new StringBuilder(dataRang[i]); 247 | //string v = dataRang[i].Text; 248 | string v = v1.ToString().TrimEnd(); 249 | 250 | switch (fieldType) 251 | { 252 | case "I": 253 | { 254 | stringBuilder.Append(Convert.ToInt64(v)); 255 | } 256 | break; 257 | case "F": 258 | { 259 | stringBuilder.AppendFormat("{0:F}",Convert.ToDouble(v)); 260 | } 261 | break; 262 | case "S": 263 | { 264 | v = v.Replace('\r', ' '); 265 | v = v.Replace('\n', ' '); 266 | stringBuilder.Append("\"" + v + "\""); 267 | } 268 | break; 269 | case "B": 270 | { 271 | v = v.Trim(); 272 | v = v.ToLower(); 273 | if (v.Equals("0") || v.Equals(bool.FalseString.ToLower())) 274 | { 275 | stringBuilder.Append(bool.FalseString.ToLower()); 276 | } 277 | else if (v.Equals("1") || v.Equals(bool.TrueString.ToLower())) 278 | { 279 | stringBuilder.Append(bool.TrueString.ToLower()); 280 | } 281 | else 282 | { 283 | MessageBox.Show("错误的类型: [ " + fieldType + " ]"); 284 | } 285 | } 286 | break; 287 | default: 288 | { 289 | MessageBox.Show("错误的类型: [ " + fieldType + " ]"); 290 | } 291 | break; 292 | } 293 | } 294 | else 295 | { 296 | stringBuilder.Append(""); 297 | } 298 | if (i != Keys.Count - 1) 299 | { 300 | stringBuilder.Append(","); 301 | } 302 | } 303 | stringBuilder.Append("},"); 304 | } 305 | stringBuilder.Remove(stringBuilder.Length - 1, 1); 306 | stringBuilder.Append("]"); 307 | string json = stringBuilder.ToString(); 308 | this.Save(json); 309 | 310 | UnityCS cs = new UnityCS(); 311 | cs.Export(fileName[0], typeRang, keyRang,Des); 312 | } 313 | 314 | 315 | 316 | 317 | /// 318 | /// 319 | /// 320 | /// 321 | /// 322 | /// 是否判null 323 | /// 324 | private List GetLine(Excel.Worksheet sheet, int lineNum,bool assert = true) 325 | { 326 | char a = 'A'; 327 | char z = 'Z'; 328 | 329 | int col = 1000; 330 | 331 | string colStr = ""; 332 | List _Cells = new List(); 333 | 334 | for (int c = 0; c < col; ++c) 335 | { 336 | string rStr = string.Format("{0}{1}", colStr + a, lineNum); 337 | a++; 338 | if (a > z) 339 | { 340 | a = 'A'; 341 | colStr += a; 342 | } 343 | Excel.Range line = sheet.get_Range(rStr); 344 | string tempV = line.Text; 345 | if (string.IsNullOrEmpty(tempV)) 346 | { 347 | if(assert || c == typeRang.Count) 348 | { 349 | break; 350 | } 351 | if(c < typeRang.Count) 352 | { 353 | string type = ((string)typeRang[c]).Trim(); 354 | switch (type) 355 | { 356 | case "I": 357 | case "F": 358 | case "B": 359 | { 360 | tempV = "0"; 361 | } 362 | break; 363 | case "S": 364 | { 365 | tempV = ""; 366 | } 367 | break; 368 | default: 369 | { 370 | MessageBox.Show("错误的类型: [ " + type + " ]"); 371 | } 372 | break; 373 | } 374 | } 375 | } 376 | _Cells.Add(tempV); 377 | } 378 | 379 | int index = 0; 380 | List tempDataRang = _Cells.FindAll((string s) => 381 | { 382 | if (string.IsNullOrEmpty(s) || s.Equals("0")) 383 | { 384 | if (++index == _Cells.Count) 385 | { 386 | _Cells.Clear(); 387 | } 388 | return true; 389 | } 390 | 391 | return false; 392 | }); 393 | return _Cells; 394 | } 395 | } 396 | } -------------------------------------------------------------------------------- /ExportJson/ExportJson.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 | -------------------------------------------------------------------------------- /ExportJson/ExportJsonPlugin.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 21 | 22 | {BAA0C2D2-18E2-41B9-852F-F413020CAA33};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 23 | Debug 24 | AnyCPU 25 | {1FD54CD9-CF79-438A-BA29-29F49C6EFAD1} 26 | Library 27 | false 28 | ExportJson 29 | ExportJson 30 | v4.5 31 | VSTO40 32 | True 33 | 34 | true 35 | F:\GitHub\ExportJson-for-Excel-2014\Download\ 36 | https://github.com/wanggan768q/ExportJson-for-Excel-2014/blob/master/Download/ 37 | zh-chs 38 | 1.1.0.32 39 | true 40 | true 41 | 0 42 | days 43 | ExportJson 44 | 郭晓波 45 | 46 | ExportJson 47 | 48 | 3 49 | 50 | 51 | 52 | False 53 | Microsoft .NET Framework 4 %28x86 和 x64%29 54 | true 55 | 56 | 57 | False 58 | Microsoft .NET Framework 4.5 %28x86 和 x64%29 59 | true 60 | 61 | 62 | False 63 | .NET Framework 3.5 SP1 Client Profile 64 | false 65 | 66 | 67 | False 68 | .NET Framework 3.5 SP1 69 | false 70 | 71 | 72 | False 73 | Microsoft Visual Studio 2010 Tools for Office Runtime %28x86 和 x64%29 74 | true 75 | 76 | 77 | False 78 | Windows Installer 4.5 79 | true 80 | 81 | 82 | 83 | 87 | Excel 88 | 89 | 105 | 106 | true 107 | full 108 | false 109 | bin\Debug\ 110 | false 111 | $(DefineConstants);DEBUG;TRACE 112 | 4 113 | false 114 | 115 | 131 | 132 | pdbonly 133 | true 134 | bin\Release\ 135 | false 136 | $(DefineConstants);TRACE 137 | 4 138 | false 139 | 140 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | True 165 | 166 | 167 | 168 | 169 | False 170 | true 171 | 172 | 173 | False 174 | true 175 | 176 | 177 | False 178 | 179 | 180 | 190 | 191 | 192 | Component 193 | 194 | 195 | ExportJson.cs 196 | 197 | 198 | 199 | Code 200 | 201 | 202 | 203 | 204 | 205 | ExportJson.cs 206 | 207 | 208 | PublicResXFileCodeGenerator 209 | Resources.Designer.cs 210 | Designer 211 | 212 | 213 | True 214 | Resources.resx 215 | True 216 | 217 | 218 | 219 | 220 | SettingsSingleFileGenerator 221 | Settings.Designer.cs 222 | 223 | 224 | True 225 | Settings.settings 226 | True 227 | 228 | 229 | 230 | Code 231 | 232 | 233 | ThisAddIn.cs 234 | 235 | 236 | ThisAddIn.Designer.xml 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 10.0 251 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 252 | 253 | 254 | true 255 | 256 | 257 | 258 | 259 | 260 | 261 | 63EA093DAAA4BF3586973B0875A7EE64BC188154 262 | 263 | 264 | 265 | 266 | 267 | true 268 | 269 | 270 | ExportJson_TemporaryKey.pfx 271 | 272 | 273 | 274 | 275 | 276 | 277 | false 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | -------------------------------------------------------------------------------- /ExportJson/ExportJsonPlugin.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | F:\GitHub\ExportJson-for-Excel-2014\Download\ 5 | https://github.com/wanggan768q/ExportJson-for-Excel-2014/blob/master/Download/ 6 | 7 | ProjectFiles 8 | 9 | 10 | Project 11 | false 12 | 13 | -------------------------------------------------------------------------------- /ExportJson/ExportJson_TemporaryKey.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/ExportJson/ExportJson_TemporaryKey.pfx -------------------------------------------------------------------------------- /ExportJson/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using System.Security; 5 | 6 | // 有关程序集的常规信息通过下列特性集 7 | // 控制。更改这些特性值可修改 8 | // 与程序集关联的信息。 9 | [assembly: AssemblyTitle("ExportJson")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("ExportJson")] 14 | [assembly: AssemblyCopyright("Copyright © 2015")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // 将 ComVisible 设置为 false 会使此程序集中的类型 19 | // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 20 | // 则将该类型的 ComVisible 特性设置为 true。 21 | [assembly: ComVisible(false)] 22 | 23 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 24 | [assembly: Guid("d58d077d-b0ed-4e66-a749-badd3b90db05")] 25 | 26 | // 程序集的版本信息由下面四个值组成: 27 | // 28 | // 主版本 29 | // 次版本 30 | // 生成号 31 | // 修订号 32 | // 33 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 34 | // 方法是按如下所示使用“*”: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | 39 | -------------------------------------------------------------------------------- /ExportJson/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ExportJson.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 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 | public 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 | public 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("ExportJson.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 | public static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找类似 using UnityEngine; 65 | ///using System.Collections; 66 | /// 67 | ///public class ConfigLoad : MonoBehaviour { 68 | /// 69 | /// private string textContent; 70 | /// 71 | /// public IEnumerator LoadConfig () { 72 | /// 73 | ///$loadConfItem$ 74 | /// 75 | /// yield return true; 76 | /// } 77 | /// 78 | /// IEnumerator LoadData (string name) { 79 | /// 80 | /// string path = Ex.Utils.GetStreamingAssetsFilePath(name, "CSV"); 81 | /// 82 | /// WWW www = new WWW(path); 83 | /// yield return www; 84 | /// 85 | /// textContent = www.text; 86 | /// yield return true; 87 | /// } 88 | ///} 89 | /// 的本地化字符串。 90 | /// 91 | public static string ConfigLoadTemplate { 92 | get { 93 | return ResourceManager.GetString("ConfigLoadTemplate", resourceCulture); 94 | } 95 | } 96 | 97 | /// 98 | /// 查找类似 using UnityEngine; 99 | ///using System; 100 | ///using System.IO; 101 | ///using System.Collections; 102 | ///using System.Collections.Generic; 103 | ///using HS.IO; 104 | ///using LitJson; 105 | /// 106 | /// 107 | ///public class $Template$Element 108 | ///{ 109 | ///$FieldDefine$ 110 | /// public bool IsValidate = false; 111 | /// public $Template$Element() 112 | /// { 113 | /// $InitPrimaryField$ 114 | /// } 115 | ///}; 116 | /// 117 | /// 118 | ///public class $Template$Table 119 | ///{ 120 | /// 121 | /// private $Template$Table() 122 | /// { 123 | /// _MapElements = new Dictionary<int, $Template$Element>(); 124 | /// _EmptyItem = new $Template$Element(); 125 | /// _VecAllElements = new List<$Template$Eleme [字符串的其余部分被截断]"; 的本地化字符串。 126 | /// 127 | public static string ConfigTemplate { 128 | get { 129 | return ResourceManager.GetString("ConfigTemplate", resourceCulture); 130 | } 131 | } 132 | 133 | /// 134 | /// 查找类似于 (Icon) 的 System.Drawing.Icon 类型的本地化资源。 135 | /// 136 | public static System.Drawing.Icon josn_icon { 137 | get { 138 | object obj = ResourceManager.GetObject("josn_icon", resourceCulture); 139 | return ((System.Drawing.Icon)(obj)); 140 | } 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /ExportJson/Properties/Resources.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 | 122 | ..\res\ConfigLoadTemplate.cs;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 123 | 124 | 125 | ..\res\ConfigTemplate.cs;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;gb2312 126 | 127 | 128 | ..\res\josn_icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | -------------------------------------------------------------------------------- /ExportJson/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ExportJsonPlugin.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.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 | -------------------------------------------------------------------------------- /ExportJson/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ExportJson/Settings.cs: -------------------------------------------------------------------------------- 1 | namespace ExportJsonPlugin.Properties { 2 | 3 | 4 | // 通过此类可以处理设置类的特定事件: 5 | // 在更改某个设置的值之前将引发 SettingChanging 事件。 6 | // 在更改某个设置的值之后将引发 PropertyChanged 事件。 7 | // 在加载设置值之后将引发 SettingsLoaded 事件。 8 | // 在保存设置值之前将引发 SettingsSaving 事件。 9 | internal sealed partial class Settings { 10 | 11 | public Settings() { 12 | // // 若要为保存和更改设置添加事件处理程序,请取消注释下列行: 13 | // 14 | // this.SettingChanging += this.SettingChangingEventHandler; 15 | // 16 | // this.SettingsSaving += this.SettingsSavingEventHandler; 17 | // 18 | } 19 | 20 | private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) { 21 | // 在此处添加用于处理 SettingChangingEvent 事件的代码。 22 | } 23 | 24 | private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) { 25 | // 在此处添加用于处理 SettingsSaving 事件的代码。 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ExportJson/ThisAddIn.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | #pragma warning disable 414 12 | namespace ExportJsonPlugin { 13 | 14 | 15 | /// 16 | [Microsoft.VisualStudio.Tools.Applications.Runtime.StartupObjectAttribute(0)] 17 | [global::System.Security.Permissions.PermissionSetAttribute(global::System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")] 18 | public sealed partial class ThisAddIn : Microsoft.Office.Tools.AddInBase { 19 | 20 | internal Microsoft.Office.Tools.CustomTaskPaneCollection CustomTaskPanes; 21 | 22 | internal Microsoft.Office.Tools.SmartTagCollection VstoSmartTags; 23 | 24 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 25 | private global::System.Object missing = global::System.Type.Missing; 26 | 27 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 28 | internal Microsoft.Office.Interop.Excel.Application Application; 29 | 30 | /// 31 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 32 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 33 | public ThisAddIn(global::Microsoft.Office.Tools.Excel.ApplicationFactory factory, global::System.IServiceProvider serviceProvider) : 34 | base(factory, serviceProvider, "AddIn", "ThisAddIn") { 35 | Globals.Factory = factory; 36 | } 37 | 38 | /// 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 41 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 42 | protected override void Initialize() { 43 | base.Initialize(); 44 | this.Application = this.GetHostItem(typeof(Microsoft.Office.Interop.Excel.Application), "Application"); 45 | Globals.ThisAddIn = this; 46 | global::System.Windows.Forms.Application.EnableVisualStyles(); 47 | this.InitializeCachedData(); 48 | this.InitializeControls(); 49 | this.InitializeComponents(); 50 | this.InitializeData(); 51 | } 52 | 53 | /// 54 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 55 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 56 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 57 | protected override void FinishInitialization() { 58 | this.InternalStartup(); 59 | this.OnStartup(); 60 | } 61 | 62 | /// 63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 65 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 66 | protected override void InitializeDataBindings() { 67 | this.BeginInitialization(); 68 | this.BindToData(); 69 | this.EndInitialization(); 70 | } 71 | 72 | /// 73 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 74 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 75 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 76 | private void InitializeCachedData() { 77 | if ((this.DataHost == null)) { 78 | return; 79 | } 80 | if (this.DataHost.IsCacheInitialized) { 81 | this.DataHost.FillCachedData(this); 82 | } 83 | } 84 | 85 | /// 86 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 87 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 88 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 89 | private void InitializeData() { 90 | } 91 | 92 | /// 93 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 94 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 95 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 96 | private void BindToData() { 97 | } 98 | 99 | /// 100 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 101 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 102 | private void StartCaching(string MemberName) { 103 | this.DataHost.StartCaching(this, MemberName); 104 | } 105 | 106 | /// 107 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 108 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 109 | private void StopCaching(string MemberName) { 110 | this.DataHost.StopCaching(this, MemberName); 111 | } 112 | 113 | /// 114 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 115 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 116 | private bool IsCached(string MemberName) { 117 | return this.DataHost.IsCached(this, MemberName); 118 | } 119 | 120 | /// 121 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 122 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 123 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 124 | private void BeginInitialization() { 125 | this.BeginInit(); 126 | this.CustomTaskPanes.BeginInit(); 127 | this.VstoSmartTags.BeginInit(); 128 | } 129 | 130 | /// 131 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 132 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 133 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 134 | private void EndInitialization() { 135 | this.VstoSmartTags.EndInit(); 136 | this.CustomTaskPanes.EndInit(); 137 | this.EndInit(); 138 | } 139 | 140 | /// 141 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 142 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 143 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 144 | private void InitializeControls() { 145 | this.CustomTaskPanes = Globals.Factory.CreateCustomTaskPaneCollection(null, null, "CustomTaskPanes", "CustomTaskPanes", this); 146 | this.VstoSmartTags = Globals.Factory.CreateSmartTagCollection(null, null, "VstoSmartTags", "VstoSmartTags", this); 147 | } 148 | 149 | /// 150 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 151 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 152 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 153 | private void InitializeComponents() { 154 | } 155 | 156 | /// 157 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 158 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 159 | private bool NeedsFill(string MemberName) { 160 | return this.DataHost.NeedsFill(this, MemberName); 161 | } 162 | 163 | /// 164 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 165 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 166 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] 167 | protected override void OnShutdown() { 168 | this.VstoSmartTags.Dispose(); 169 | this.CustomTaskPanes.Dispose(); 170 | base.OnShutdown(); 171 | } 172 | } 173 | 174 | /// 175 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 176 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 177 | internal sealed partial class Globals { 178 | 179 | /// 180 | private Globals() { 181 | } 182 | 183 | private static ThisAddIn _ThisAddIn; 184 | 185 | private static global::Microsoft.Office.Tools.Excel.ApplicationFactory _factory; 186 | 187 | private static ThisRibbonCollection _ThisRibbonCollection; 188 | 189 | internal static ThisAddIn ThisAddIn { 190 | get { 191 | return _ThisAddIn; 192 | } 193 | set { 194 | if ((_ThisAddIn == null)) { 195 | _ThisAddIn = value; 196 | } 197 | else { 198 | throw new System.NotSupportedException(); 199 | } 200 | } 201 | } 202 | 203 | internal static global::Microsoft.Office.Tools.Excel.ApplicationFactory Factory { 204 | get { 205 | return _factory; 206 | } 207 | set { 208 | if ((_factory == null)) { 209 | _factory = value; 210 | } 211 | else { 212 | throw new System.NotSupportedException(); 213 | } 214 | } 215 | } 216 | 217 | internal static ThisRibbonCollection Ribbons { 218 | get { 219 | if ((_ThisRibbonCollection == null)) { 220 | _ThisRibbonCollection = new ThisRibbonCollection(_factory.GetRibbonFactory()); 221 | } 222 | return _ThisRibbonCollection; 223 | } 224 | } 225 | } 226 | 227 | /// 228 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 229 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Tools.Office.ProgrammingModel.dll", "14.0.0.0")] 230 | internal sealed partial class ThisRibbonCollection : Microsoft.Office.Tools.Ribbon.RibbonCollectionBase { 231 | 232 | /// 233 | internal ThisRibbonCollection(global::Microsoft.Office.Tools.Ribbon.RibbonFactory factory) : 234 | base(factory) { 235 | } 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /ExportJson/ThisAddIn.Designer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ExportJson/ThisAddIn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Xml.Linq; 6 | using Excel = Microsoft.Office.Interop.Excel; 7 | using Office = Microsoft.Office.Core; 8 | using Microsoft.Office.Tools.Excel; 9 | using System.Text.RegularExpressions; 10 | using System.IO; 11 | using Microsoft.Office.Tools.Ribbon; 12 | 13 | namespace ExportJsonPlugin 14 | { 15 | public partial class ThisAddIn 16 | { 17 | private void ThisAddIn_Startup(object sender, System.EventArgs e) 18 | { 19 | //this.Application.WorkbookBeforeSave += new Microsoft.Office.Interop.Excel.AppEvents_WorkbookBeforeSaveEventHandler(Application_WorkbookBeforeSave); 20 | } 21 | 22 | private void ThisAddIn_Shutdown(object sender, System.EventArgs e) 23 | { 24 | } 25 | 26 | #region VSTO 生成的代码 27 | 28 | /// 29 | /// 设计器支持所需的方法 - 不要 30 | /// 使用代码编辑器修改此方法的内容。 31 | /// 32 | private void InternalStartup() 33 | { 34 | this.Startup += new System.EventHandler(ThisAddIn_Startup); 35 | this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown); 36 | } 37 | #endregion 38 | 39 | protected override IRibbonExtension[] CreateRibbonObjects() 40 | { 41 | return new IRibbonExtension[] { new ExportJson() }; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ExportJson/UnityCS.cs: -------------------------------------------------------------------------------- 1 | using ExportJson.Properties; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace ExportJsonPlugin 8 | { 9 | class UnityCS 10 | { 11 | public const string T1 = "\t"; 12 | public const string T2 = "\t\t"; 13 | public const string T3 = "\t\t\t"; 14 | public const string T4 = "\t\t\t\t"; 15 | 16 | private string WorkbookFullName 17 | { 18 | get 19 | { 20 | return Globals.ThisAddIn.Application.ActiveWorkbook.FullName; 21 | } 22 | } 23 | 24 | private string CSPath 25 | { 26 | get 27 | { 28 | return Path.GetDirectoryName(Globals.ThisAddIn.Application.ActiveWorkbook.FullName) + Path.DirectorySeparatorChar + "Out" + Path.DirectorySeparatorChar + "config"; 29 | } 30 | } 31 | 32 | 33 | Dictionary templateDir = new Dictionary() 34 | { 35 | {"$Template$",new StringBuilder() }, 36 | {"$FieldDefine$",new StringBuilder() }, 37 | {"$ColCount$",new StringBuilder() }, 38 | {"$CheckColName$",new StringBuilder() }, 39 | {"$ReadBinColValue$",new StringBuilder() }, 40 | {"$ReadCsvColValue$",new StringBuilder() }, 41 | {"$InitPrimaryField$",new StringBuilder() }, 42 | {"$PrimaryKey$",new StringBuilder() }, 43 | {"$ReadJsonColValue$",new StringBuilder() }, 44 | }; 45 | 46 | string name = ""; 47 | StringBuilder sb = new StringBuilder(); 48 | public void Export(string fileName, List type, List key, List des) 49 | { 50 | string[] titles = fileName.Split('_'); 51 | name = titles[0]; 52 | 53 | templateDir["$Template$"].Append(name); 54 | templateDir["$PrimaryKey$"].Append(key[0]); 55 | 56 | AddField(templateDir["$FieldDefine$"], type, key,des); 57 | 58 | templateDir["$ColCount$"].Append(key.Count); 59 | 60 | CheckColName(templateDir["$CheckColName$"],key,name); 61 | 62 | ReadBinColValue(templateDir["$ReadBinColValue$"], type, key); 63 | 64 | ReadCsvColValue(templateDir["$ReadCsvColValue$"], type, key); 65 | 66 | InitPrimaryField(templateDir["$InitPrimaryField$"], templateDir["$PrimaryKey$"].ToString()); 67 | 68 | ReadJsonColValue(templateDir["$ReadJsonColValue$"],type,key); 69 | 70 | string text = Resources.ConfigTemplate; 71 | 72 | foreach(var dir in templateDir) 73 | { 74 | text = text.Replace(dir.Key, dir.Value.ToString()); 75 | } 76 | 77 | 78 | if(!Directory.Exists(CSPath)) 79 | { 80 | Directory.CreateDirectory(CSPath); 81 | } 82 | string path = CSPath+ Path.DirectorySeparatorChar + name + ".cs"; 83 | StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8); 84 | sw.Write(text); 85 | sw.Flush(); 86 | sw.Close(); 87 | 88 | GenerateConfigLoad(); 89 | } 90 | 91 | private void GenerateConfigLoad() 92 | { 93 | Dictionary dir = new Dictionary() 94 | { 95 | {"$loadConfItem$",new StringBuilder() }, 96 | {"$fileCount$",new StringBuilder() } 97 | }; 98 | int fileCount = 0; 99 | string[] files = Directory.GetFiles(Path.GetDirectoryName(WorkbookFullName)); 100 | foreach (string s in files) 101 | { 102 | string file = Path.GetFileName(s).Split('_')[0]; 103 | string suffix = ".json"; 104 | if (!file.Contains('~')) 105 | { 106 | fileCount++; 107 | StringBuilder sb = dir["$loadConfItem$"]; 108 | sb.AppendFormat(T2 + E("yield return StartCoroutine(LoadData(\"{0}" + suffix + "\"));"), file); 109 | sb.AppendFormat(T2 + E("{0}Table.Instance.LoadJson(textContent);"), file); 110 | sb.AppendFormat(T2 + E("Progress({0});"), fileCount); 111 | } 112 | } 113 | dir["$fileCount$"].Append(fileCount); 114 | 115 | string text = Resources.ConfigLoadTemplate; 116 | foreach (var d in dir) 117 | { 118 | text = text.Replace(d.Key, d.Value.ToString()); 119 | } 120 | string path = CSPath + Path.DirectorySeparatorChar + "ConfigLoad.cs"; 121 | StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8); 122 | sw.Write(text); 123 | sw.Flush(); 124 | sw.Close(); 125 | } 126 | 127 | void ReadJsonColValue(StringBuilder sb, List type, List key) 128 | { 129 | for (int i = 0; i < key.Count; ++i) 130 | { 131 | switch (type[i]) 132 | { 133 | case "I": 134 | sb.AppendFormat(T3 + E("member.{0} = (int)jd[\"{1}\"];"), key[i], key[i]); 135 | break; 136 | case "F": 137 | sb.AppendFormat(T3 + E("member.{0} = (float)((double)jd[\"{1}\"]);"), key[i], key[i]); 138 | break; 139 | case "B": 140 | sb.AppendFormat(T3 + E("member.{0} = (bool)jd[\"{1}\"];"), key[i], key[i]); 141 | break; 142 | case "S": 143 | sb.AppendFormat(T3 + E("member.{0} = (string)jd[\"{1}\"];"), key[i], key[i]); 144 | break; 145 | } 146 | } 147 | } 148 | 149 | void InitPrimaryField(StringBuilder sb, string key) 150 | { 151 | sb.AppendLine(T2 + key + " = 0;"); 152 | sb.AppendLine(T2 + "IsValidate = false;"); 153 | } 154 | 155 | void ReadCsvColValue(StringBuilder sb, List type, List key) 156 | { 157 | for (int i=0;i key,string name) 179 | { 180 | for (int i = 0; i < key.Count; ++i) 181 | { 182 | sb.AppendFormat(T2 + E("if(vecLine[{0}]!=\"{1}\") {{ Debug.Log(\"{2}.json中字段[{3}]位置不对应\"); return false; }}"), 183 | i, key[i], name, key[i], name); 184 | } 185 | sb.AppendLine(); 186 | } 187 | 188 | void ReadBinColValue(StringBuilder sb,List type,List key) 189 | { 190 | for (int i = 0; i < key.Count; ++i) 191 | { 192 | switch (type[i]) 193 | { 194 | case "I": 195 | sb.AppendFormat(T3 + E("readPos += HS_ByteRead.ReadInt32Variant(binContent, readPos, out member.{0} );"), key[i]); 196 | break; 197 | case "F": 198 | sb.AppendFormat(T3 + E("readPos += HS_ByteRead.ReadFloat(binContent, readPos, out member.{0} );"), key[i]); 199 | break; 200 | case "B": 201 | sb.AppendFormat(T3 + E("readPos += HS_ByteRead.ReadBool(binContent, readPos, out member.{0} );"), key[i]); 202 | break; 203 | case "S": 204 | sb.AppendFormat(T3 + E("readPos += HS_ByteRead.ReadString(binContent, readPos, out member.{0} );"), key[i]); 205 | break; 206 | } 207 | 208 | } 209 | } 210 | 211 | 212 | string E(string s="") 213 | { 214 | return s + "\r\n"; 215 | } 216 | 217 | void AddTitle(StringBuilder sb,string title) 218 | { 219 | sb.AppendLine(T1 + "/// "); 220 | sb.AppendFormat(E(T1 + "/// {0}"), title); 221 | sb.AppendLine(T1 + "/// "); 222 | } 223 | 224 | /// 225 | /// 添加字段 226 | /// 227 | /// 228 | /// 229 | /// 230 | /// 231 | void AddField(StringBuilder sb,List type, List key, List des) 232 | { 233 | for(int i=0;i 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ExportJson/fastJSON.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections; 3 | using System.Data; 4 | using System.Globalization; 5 | using System.IO; 6 | using System.Reflection.Emit; 7 | using System.Reflection; 8 | using System.Text; 9 | using System; 10 | 11 | namespace fastJSON 12 | { 13 | internal static class Formatter 14 | { 15 | public static string Indent = " "; 16 | 17 | public static void AppendIndent(StringBuilder sb, int count) 18 | { 19 | for (; count > 0; --count) sb.Append(Indent); 20 | } 21 | 22 | public static bool IsEscaped(StringBuilder sb, int index) 23 | { 24 | bool escaped = false; 25 | while (index > 0 && sb[--index] == '\\') escaped = !escaped; 26 | return escaped; 27 | } 28 | 29 | public static string PrettyPrint(string input) 30 | { 31 | var output = new StringBuilder(input.Length * 2); 32 | char? quote = null; 33 | int depth = 0; 34 | 35 | for (int i = 0; i < input.Length; ++i) 36 | { 37 | char ch = input[i]; 38 | 39 | switch (ch) 40 | { 41 | case '{': 42 | case '[': 43 | output.Append(ch); 44 | if (!quote.HasValue) 45 | { 46 | output.AppendLine(); 47 | AppendIndent(output, ++depth); 48 | } 49 | break; 50 | case '}': 51 | case ']': 52 | if (quote.HasValue) 53 | output.Append(ch); 54 | else 55 | { 56 | output.AppendLine(); 57 | AppendIndent(output, --depth); 58 | output.Append(ch); 59 | } 60 | break; 61 | case '"': 62 | case '\'': 63 | output.Append(ch); 64 | if (quote.HasValue) 65 | { 66 | if (!IsEscaped(output, i)) 67 | quote = null; 68 | } 69 | else quote = ch; 70 | break; 71 | case ',': 72 | output.Append(ch); 73 | if (!quote.HasValue) 74 | { 75 | output.AppendLine(); 76 | AppendIndent(output, depth); 77 | } 78 | break; 79 | case ':': 80 | if (quote.HasValue) output.Append(ch); 81 | else output.Append(" : "); 82 | break; 83 | default: 84 | if (quote.HasValue || !char.IsWhiteSpace(ch)) 85 | output.Append(ch); 86 | break; 87 | } 88 | } 89 | 90 | return output.ToString(); 91 | } 92 | } 93 | } 94 | 95 | namespace fastJSON 96 | { 97 | public sealed class DatasetSchema 98 | { 99 | public List Info { get; set; } 100 | public string Name { get; set; } 101 | } 102 | } 103 | 104 | namespace fastJSON 105 | { 106 | public delegate string Serialize(object data); 107 | public delegate object Deserialize(string data); 108 | 109 | public sealed class JSONParameters 110 | { 111 | /// 112 | /// Use the optimized fast Dataset Schema format (default = True) 113 | /// 114 | public bool UseOptimizedDatasetSchema = true; 115 | /// 116 | /// Use the fast GUID format (default = True) 117 | /// 118 | public bool UseFastGuid = true; 119 | /// 120 | /// Serialize null values to the output (default = True) 121 | /// 122 | public bool SerializeNullValues = true; 123 | /// 124 | /// Use the UTC date format (default = True) 125 | /// 126 | public bool UseUTCDateTime = true; 127 | /// 128 | /// Show the readonly properties of types in the output (default = False) 129 | /// 130 | public bool ShowReadOnlyProperties = false; 131 | /// 132 | /// Use the $types extension to optimise the output json (default = True) 133 | /// 134 | public bool UsingGlobalTypes = true; 135 | /// 136 | /// ** work in progress 137 | /// 138 | public bool IgnoreCaseOnDeserialize = false; 139 | /// 140 | /// Anonymous types have read only properties 141 | /// 142 | public bool EnableAnonymousTypes = false; 143 | /// 144 | /// Enable fastJSON extensions $types, $type, $map (default = True) 145 | /// 146 | public bool UseExtensions = true; 147 | /// 148 | /// Use escaped unicode i.e. \uXXXX format for non ASCII characters (default = True) 149 | /// 150 | public bool UseEscapedUnicode = true; 151 | 152 | public void FixValues() 153 | { 154 | if (UseExtensions == false) // disable conflicting params 155 | { 156 | UsingGlobalTypes = false; 157 | } 158 | } 159 | } 160 | 161 | public sealed class JSON 162 | { 163 | //public readonly static JSON Instance = new JSON(); 164 | [ThreadStatic] 165 | private static JSON _instance; 166 | 167 | public static JSON Instance 168 | { 169 | get { return _instance ?? (_instance = new JSON()); } 170 | } 171 | 172 | private JSON() 173 | { 174 | } 175 | /// 176 | /// You can set these paramters globally for all calls 177 | /// 178 | public JSONParameters Parameters = new JSONParameters(); 179 | private JSONParameters _params; 180 | 181 | public string ToJSON(object obj) 182 | { 183 | _params = Parameters; 184 | _params.FixValues(); 185 | Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties; 186 | return ToJSON(obj, Parameters); 187 | } 188 | 189 | public string ToJSON(object obj, JSONParameters param) 190 | { 191 | _params = param; 192 | _params.FixValues(); 193 | Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties; 194 | Type t = null; 195 | 196 | if (obj == null) 197 | return "null"; 198 | 199 | if (obj.GetType().IsGenericType) 200 | t = obj.GetType().GetGenericTypeDefinition(); 201 | if (t == typeof(Dictionary<,>) || t == typeof(List<>)) 202 | _params.UsingGlobalTypes = false; 203 | 204 | // FEATURE : enable extensions when you can deserialize anon types 205 | if (_params.EnableAnonymousTypes) { _params.UseExtensions = false; _params.UsingGlobalTypes = false; Reflection.Instance.ShowReadOnlyProperties = true; } 206 | _usingglobals = _params.UsingGlobalTypes; 207 | return new JSONSerializer(_params).ConvertToJSON(obj); 208 | } 209 | 210 | public object Parse(string json) 211 | { 212 | _params = Parameters; 213 | Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties; 214 | return new JsonParser(json, _params.IgnoreCaseOnDeserialize).Decode(); 215 | } 216 | 217 | public T ToObject(string json) 218 | { 219 | return (T)ToObject(json, typeof(T)); 220 | } 221 | 222 | public object ToObject(string json) 223 | { 224 | return ToObject(json, null); 225 | } 226 | 227 | public object ToObject(string json, Type type) 228 | { 229 | _params = Parameters; 230 | _params.FixValues(); 231 | Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties; 232 | Type t = null; 233 | if (type != null && type.IsGenericType) 234 | t = type.GetGenericTypeDefinition(); 235 | if (t == typeof(Dictionary<,>) || t == typeof(List<>)) 236 | _params.UsingGlobalTypes = false; 237 | _usingglobals = _params.UsingGlobalTypes; 238 | 239 | object o = new JsonParser(json, Parameters.IgnoreCaseOnDeserialize).Decode(); 240 | if (o == null) 241 | return null; 242 | 243 | #if !SILVERLIGHT 244 | if (type != null && type == typeof(DataSet)) 245 | return CreateDataset(o as Dictionary, null); 246 | 247 | if (type != null && type == typeof(DataTable)) 248 | return CreateDataTable(o as Dictionary, null); 249 | #endif 250 | if (o is IDictionary) 251 | { 252 | if (type != null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)) // deserialize a dictionary 253 | return RootDictionary(o, type); 254 | else // deserialize an object 255 | return ParseDictionary(o as Dictionary, null, type, null); 256 | } 257 | 258 | if (o is List) 259 | { 260 | if (type != null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)) // kv format 261 | return RootDictionary(o, type); 262 | 263 | if (type != null && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) // deserialize to generic list 264 | return RootList(o, type); 265 | else 266 | return (o as List).ToArray(); 267 | } 268 | 269 | if (type!=null && o.GetType() != type) 270 | return ChangeType(o, type); 271 | 272 | return o; 273 | } 274 | 275 | public string Beautify(string input) 276 | { 277 | return Formatter.PrettyPrint(input); 278 | } 279 | 280 | public object FillObject(object input, string json) 281 | { 282 | _params = Parameters; 283 | _params.FixValues(); 284 | Reflection.Instance.ShowReadOnlyProperties = _params.ShowReadOnlyProperties; 285 | Dictionary ht = new JsonParser(json, Parameters.IgnoreCaseOnDeserialize).Decode() as Dictionary; 286 | if (ht == null) return null; 287 | return ParseDictionary(ht, null, input.GetType(), input); 288 | } 289 | 290 | public object DeepCopy(object obj) 291 | { 292 | return ToObject(ToJSON(obj)); 293 | } 294 | 295 | public T DeepCopy(T obj) 296 | { 297 | return ToObject(ToJSON(obj)); 298 | } 299 | 300 | #if CUSTOMTYPE 301 | internal SafeDictionary _customSerializer = new SafeDictionary(); 302 | internal SafeDictionary _customDeserializer = new SafeDictionary(); 303 | 304 | public void RegisterCustomType(Type type, Serialize serializer, Deserialize deserializer) 305 | { 306 | if (type != null && serializer != null && deserializer != null) 307 | { 308 | _customSerializer.Add(type, serializer); 309 | _customDeserializer.Add(type, deserializer); 310 | // reset property cache 311 | _propertycache = new SafeDictionary>(); 312 | } 313 | } 314 | 315 | internal bool IsTypeRegistered(Type t) 316 | { 317 | Serialize s; 318 | return _customSerializer.TryGetValue(t, out s); 319 | } 320 | #endif 321 | 322 | #region [ JSON specific reflection ] 323 | 324 | private struct myPropInfo 325 | { 326 | public bool filled; 327 | public Type pt; 328 | public Type bt; 329 | public Type changeType; 330 | public bool isDictionary; 331 | public bool isValueType; 332 | public bool isGenericType; 333 | public bool isArray; 334 | public bool isByteArray; 335 | public bool isGuid; 336 | #if !SILVERLIGHT 337 | public bool isDataSet; 338 | public bool isDataTable; 339 | public bool isHashtable; 340 | #endif 341 | public Reflection.GenericSetter setter; 342 | public bool isEnum; 343 | public bool isDateTime; 344 | public Type[] GenericTypes; 345 | public bool isInt; 346 | public bool isLong; 347 | public bool isString; 348 | public bool isBool; 349 | public bool isClass; 350 | public Reflection.GenericGetter getter; 351 | public bool isStringDictionary; 352 | public string Name; 353 | #if CUSTOMTYPE 354 | public bool isCustomType; 355 | #endif 356 | public bool CanWrite; 357 | } 358 | 359 | SafeDictionary> _propertycache = new SafeDictionary>(); 360 | private SafeDictionary Getproperties(Type type, string typename) 361 | { 362 | SafeDictionary sd = null; 363 | if (_propertycache.TryGetValue(typename, out sd)) 364 | { 365 | return sd; 366 | } 367 | else 368 | { 369 | sd = new SafeDictionary(); 370 | PropertyInfo[] pr = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); 371 | foreach (PropertyInfo p in pr) 372 | { 373 | myPropInfo d = CreateMyProp(p.PropertyType, p.Name); 374 | d.CanWrite = p.CanWrite; 375 | d.setter = Reflection.CreateSetMethod(type, p); 376 | d.getter = Reflection.CreateGetMethod(type, p); 377 | sd.Add(p.Name, d); 378 | } 379 | FieldInfo[] fi = type.GetFields(BindingFlags.Public | BindingFlags.Instance); 380 | foreach (FieldInfo f in fi) 381 | { 382 | myPropInfo d = CreateMyProp(f.FieldType, f.Name); 383 | d.setter = Reflection.CreateSetField(type, f); 384 | d.getter = Reflection.CreateGetField(type, f); 385 | sd.Add(f.Name, d); 386 | } 387 | 388 | _propertycache.Add(typename, sd); 389 | return sd; 390 | } 391 | } 392 | 393 | private myPropInfo CreateMyProp(Type t, string name) 394 | { 395 | myPropInfo d = new myPropInfo(); 396 | d.filled = true; 397 | d.CanWrite = true; 398 | d.pt = t; 399 | d.Name = name; 400 | d.isDictionary = t.Name.Contains("Dictionary"); 401 | if (d.isDictionary) 402 | d.GenericTypes = t.GetGenericArguments(); 403 | d.isValueType = t.IsValueType; 404 | d.isGenericType = t.IsGenericType; 405 | d.isArray = t.IsArray; 406 | if (d.isArray) 407 | d.bt = t.GetElementType(); 408 | if (d.isGenericType) 409 | d.bt = t.GetGenericArguments()[0]; 410 | d.isByteArray = t == typeof(byte[]); 411 | d.isGuid = (t == typeof(Guid) || t == typeof(Guid?)); 412 | #if !SILVERLIGHT 413 | d.isHashtable = t == typeof(Hashtable); 414 | d.isDataSet = t == typeof(DataSet); 415 | d.isDataTable = t == typeof(DataTable); 416 | #endif 417 | 418 | d.changeType = GetChangeType(t); 419 | d.isEnum = t.IsEnum; 420 | d.isDateTime = t == typeof(DateTime) || t == typeof(DateTime?); 421 | d.isInt = t == typeof(int) || t == typeof(int?); 422 | d.isLong = t == typeof(long) || t == typeof(long?); 423 | d.isString = t == typeof(string); 424 | d.isBool = t == typeof(bool) || t == typeof(bool?); 425 | d.isClass = t.IsClass; 426 | 427 | if (d.isDictionary && d.GenericTypes.Length > 0 && d.GenericTypes[0] == typeof(string)) 428 | d.isStringDictionary = true; 429 | 430 | #if CUSTOMTYPE 431 | if (IsTypeRegistered(t)) 432 | d.isCustomType = true; 433 | #endif 434 | return d; 435 | } 436 | 437 | private object ChangeType(object value, Type conversionType) 438 | { 439 | if (conversionType == typeof(int)) 440 | return (int)((long)value); 441 | 442 | else if (conversionType == typeof(long)) 443 | return (long)value; 444 | 445 | else if (conversionType == typeof(string)) 446 | return (string)value; 447 | 448 | else if (conversionType == typeof(Guid)) 449 | return CreateGuid((string)value); 450 | 451 | else if (conversionType.IsEnum) 452 | return CreateEnum(conversionType, (string)value); 453 | #if CUSTOMTYPE 454 | else if (IsTypeRegistered(conversionType)) 455 | return CreateCustom((string)value, conversionType); 456 | #endif 457 | 458 | return Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture); 459 | } 460 | #endregion 461 | 462 | #region [ p r i v a t e m e t h o d s ] 463 | 464 | private object RootList(object parse, Type type) 465 | { 466 | Type[] gtypes = type.GetGenericArguments(); 467 | IList o = (IList)Reflection.Instance.FastCreateInstance(type); 468 | foreach (var k in (IList)parse) 469 | { 470 | _usingglobals = false; 471 | object v = k; 472 | if (k is Dictionary) 473 | v = ParseDictionary(k as Dictionary, null, gtypes[0], null); 474 | else 475 | v = ChangeType(k, gtypes[0]); 476 | 477 | o.Add(v); 478 | } 479 | return o; 480 | } 481 | 482 | private object RootDictionary(object parse, Type type) 483 | { 484 | Type[] gtypes = type.GetGenericArguments(); 485 | if (parse is Dictionary) 486 | { 487 | IDictionary o = (IDictionary)Reflection.Instance.FastCreateInstance(type); 488 | 489 | foreach (var kv in (Dictionary)parse) 490 | { 491 | object v; 492 | object k = ChangeType(kv.Key, gtypes[0]); 493 | if (kv.Value is Dictionary) 494 | v = ParseDictionary(kv.Value as Dictionary, null, gtypes[1], null); 495 | else if (kv.Value is List) 496 | v = CreateArray(kv.Value as List, typeof(object), typeof(object), null); 497 | else 498 | v = ChangeType(kv.Value, gtypes[1]); 499 | o.Add(k, v); 500 | } 501 | 502 | return o; 503 | } 504 | if (parse is List) 505 | return CreateDictionary(parse as List, type, gtypes, null); 506 | 507 | return null; 508 | } 509 | 510 | bool _usingglobals = false; 511 | private object ParseDictionary(Dictionary d, Dictionary globaltypes, Type type, object input) 512 | { 513 | object tn = ""; 514 | 515 | if (d.TryGetValue("$types", out tn)) 516 | { 517 | _usingglobals = true; 518 | globaltypes = new Dictionary(); 519 | foreach (var kv in (Dictionary)tn) 520 | { 521 | globaltypes.Add((string)kv.Value, kv.Key); 522 | } 523 | } 524 | 525 | bool found = d.TryGetValue("$type", out tn); 526 | #if !SILVERLIGHT 527 | if (found == false && type == typeof(System.Object)) 528 | { 529 | return CreateDataset(d, globaltypes); 530 | } 531 | #endif 532 | if (found) 533 | { 534 | if (_usingglobals) 535 | { 536 | object tname = ""; 537 | if (globaltypes.TryGetValue((string)tn, out tname)) 538 | tn = tname; 539 | } 540 | type = Reflection.Instance.GetTypeFromCache((string)tn); 541 | } 542 | 543 | if (type == null) 544 | throw new Exception("Cannot determine type"); 545 | 546 | string typename = type.FullName; 547 | object o = input; 548 | if (o == null) 549 | o = Reflection.Instance.FastCreateInstance(type); 550 | 551 | SafeDictionary props = Getproperties(type, typename); 552 | foreach (string n in d.Keys) 553 | { 554 | string name = n; 555 | if (_params.IgnoreCaseOnDeserialize) name = name.ToLower(); 556 | if (name == "$map") 557 | { 558 | ProcessMap(o, props, (Dictionary)d[name]); 559 | continue; 560 | } 561 | myPropInfo pi; 562 | if (props.TryGetValue(name, out pi) == false) 563 | continue; 564 | if (pi.filled && pi.CanWrite) 565 | { 566 | object v = d[name]; 567 | 568 | if (v != null) 569 | { 570 | object oset = null; 571 | 572 | if (pi.isInt) 573 | oset = (int)((long)v); 574 | #if CUSTOMTYPE 575 | else if (pi.isCustomType) 576 | oset = CreateCustom((string)v, pi.pt); 577 | #endif 578 | else if (pi.isLong) 579 | oset = (long)v; 580 | 581 | else if (pi.isString) 582 | oset = (string)v; 583 | 584 | else if (pi.isBool) 585 | oset = (bool)v; 586 | 587 | else if (pi.isGenericType && pi.isValueType == false && pi.isDictionary == false) 588 | oset = CreateGenericList((List)v, pi.pt, pi.bt, globaltypes); 589 | 590 | else if (pi.isByteArray) 591 | oset = Convert.FromBase64String((string)v); 592 | 593 | else if (pi.isArray && pi.isValueType == false) 594 | oset = CreateArray((List)v, pi.pt, pi.bt, globaltypes); 595 | 596 | else if (pi.isGuid) 597 | oset = CreateGuid((string)v); 598 | #if !SILVERLIGHT 599 | else if (pi.isDataSet) 600 | oset = CreateDataset((Dictionary)v, globaltypes); 601 | 602 | else if (pi.isDataTable) 603 | oset = this.CreateDataTable((Dictionary)v, globaltypes); 604 | #endif 605 | 606 | else if (pi.isStringDictionary) 607 | oset = CreateStringKeyDictionary((Dictionary)v, pi.pt, pi.GenericTypes, globaltypes); 608 | #if !SILVERLIGHT 609 | else if (pi.isDictionary || pi.isHashtable) 610 | #else 611 | else if (pi.isDictionary) 612 | #endif 613 | oset = CreateDictionary((List)v, pi.pt, pi.GenericTypes, globaltypes); 614 | 615 | else if (pi.isEnum) 616 | oset = CreateEnum(pi.pt, (string)v); 617 | 618 | else if (pi.isDateTime) 619 | oset = CreateDateTime((string)v); 620 | 621 | else if (pi.isClass && v is Dictionary) 622 | oset = ParseDictionary((Dictionary)v, globaltypes, pi.pt, pi.getter(o)); 623 | 624 | else if (pi.isValueType) 625 | oset = ChangeType(v, pi.changeType); 626 | 627 | else if (v is List) 628 | oset = CreateArray((List)v, pi.pt, typeof(object), globaltypes); 629 | 630 | else 631 | oset = v; 632 | 633 | o = pi.setter(o, oset); 634 | } 635 | } 636 | } 637 | return o; 638 | } 639 | 640 | #if CUSTOMTYPE 641 | private object CreateCustom(string v, Type type) 642 | { 643 | Deserialize d; 644 | _customDeserializer.TryGetValue(type, out d); 645 | return d(v); 646 | } 647 | #endif 648 | 649 | private void ProcessMap(object obj, SafeDictionary props, Dictionary dic) 650 | { 651 | foreach (KeyValuePair kv in dic) 652 | { 653 | myPropInfo p = props[kv.Key]; 654 | object o = p.getter(obj); 655 | Type t = Type.GetType((string)kv.Value); 656 | if (t == typeof(Guid)) 657 | p.setter(obj, CreateGuid((string)o)); 658 | } 659 | } 660 | 661 | private long CreateLong(string s) 662 | { 663 | long num = 0; 664 | bool neg = false; 665 | foreach (char cc in s) 666 | { 667 | if (cc == '-') 668 | neg = true; 669 | else if (cc == '+') 670 | neg = false; 671 | else 672 | { 673 | num *= 10; 674 | num += (int)(cc - '0'); 675 | } 676 | } 677 | 678 | return neg ? -num : num; 679 | } 680 | 681 | private object CreateEnum(Type pt, string v) 682 | { 683 | // TODO : optimize create enum 684 | #if !SILVERLIGHT 685 | return Enum.Parse(pt, v); 686 | #else 687 | return Enum.Parse(pt, v, true); 688 | #endif 689 | } 690 | 691 | private Guid CreateGuid(string s) 692 | { 693 | if (s.Length > 30) 694 | return new Guid(s); 695 | else 696 | return new Guid(Convert.FromBase64String(s)); 697 | } 698 | 699 | private DateTime CreateDateTime(string value) 700 | { 701 | bool utc = false; 702 | // 0123456789012345678 703 | // datetime format = yyyy-MM-dd HH:mm:ss 704 | int year = (int)CreateLong(value.Substring(0, 4)); 705 | int month = (int)CreateLong(value.Substring(5, 2)); 706 | int day = (int)CreateLong(value.Substring(8, 2)); 707 | int hour = (int)CreateLong(value.Substring(11, 2)); 708 | int min = (int)CreateLong(value.Substring(14, 2)); 709 | int sec = (int)CreateLong(value.Substring(17, 2)); 710 | 711 | if (value.EndsWith("Z")) 712 | utc = true; 713 | 714 | if (_params.UseUTCDateTime == false && utc == false) 715 | return new DateTime(year, month, day, hour, min, sec); 716 | else 717 | return new DateTime(year, month, day, hour, min, sec, DateTimeKind.Utc).ToLocalTime(); 718 | } 719 | 720 | private object CreateArray(List data, Type pt, Type bt, Dictionary globalTypes) 721 | { 722 | Array col = Array.CreateInstance(bt, data.Count); 723 | // create an array of objects 724 | for (int i = 0; i < data.Count; i++)// each (object ob in data) 725 | { 726 | object ob = data[i]; 727 | if (ob is IDictionary) 728 | col.SetValue(ParseDictionary((Dictionary)ob, globalTypes, bt, null), i); 729 | else 730 | col.SetValue(ChangeType(ob, bt), i); 731 | } 732 | 733 | return col; 734 | } 735 | 736 | 737 | private object CreateGenericList(List data, Type pt, Type bt, Dictionary globalTypes) 738 | { 739 | IList col = (IList)Reflection.Instance.FastCreateInstance(pt); 740 | // create an array of objects 741 | foreach (object ob in data) 742 | { 743 | if (ob is IDictionary) 744 | col.Add(ParseDictionary((Dictionary)ob, globalTypes, bt, null)); 745 | 746 | else if (ob is List) 747 | col.Add(((List)ob).ToArray()); 748 | 749 | else 750 | col.Add(ChangeType(ob, bt)); 751 | } 752 | return col; 753 | } 754 | 755 | private object CreateStringKeyDictionary(Dictionary reader, Type pt, Type[] types, Dictionary globalTypes) 756 | { 757 | var col = (IDictionary)Reflection.Instance.FastCreateInstance(pt); 758 | Type t1 = null; 759 | Type t2 = null; 760 | if (types != null) 761 | { 762 | t1 = types[0]; 763 | t2 = types[1]; 764 | } 765 | 766 | foreach (KeyValuePair values in reader) 767 | { 768 | var key = values.Key;//ChangeType(values.Key, t1); 769 | object val = null; 770 | if (values.Value is Dictionary) 771 | val = ParseDictionary((Dictionary)values.Value, globalTypes, t2, null); 772 | else 773 | val = ChangeType(values.Value, t2); 774 | col.Add(key, val); 775 | } 776 | 777 | return col; 778 | } 779 | 780 | private object CreateDictionary(List reader, Type pt, Type[] types, Dictionary globalTypes) 781 | { 782 | IDictionary col = (IDictionary)Reflection.Instance.FastCreateInstance(pt); 783 | Type t1 = null; 784 | Type t2 = null; 785 | if (types != null) 786 | { 787 | t1 = types[0]; 788 | t2 = types[1]; 789 | } 790 | 791 | foreach (Dictionary values in reader) 792 | { 793 | object key = values["k"]; 794 | object val = values["v"]; 795 | 796 | if (key is Dictionary) 797 | key = ParseDictionary((Dictionary)key, globalTypes, t1, null); 798 | else 799 | key = ChangeType(key, t1); 800 | 801 | if (val is Dictionary) 802 | val = ParseDictionary((Dictionary)val, globalTypes, t2, null); 803 | else 804 | val = ChangeType(val, t2); 805 | 806 | col.Add(key, val); 807 | } 808 | 809 | return col; 810 | } 811 | 812 | private Type GetChangeType(Type conversionType) 813 | { 814 | if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) 815 | return conversionType.GetGenericArguments()[0]; 816 | 817 | return conversionType; 818 | } 819 | #if !SILVERLIGHT 820 | private DataSet CreateDataset(Dictionary reader, Dictionary globalTypes) 821 | { 822 | DataSet ds = new DataSet(); 823 | ds.EnforceConstraints = false; 824 | ds.BeginInit(); 825 | 826 | // read dataset schema here 827 | ReadSchema(reader, ds, globalTypes); 828 | 829 | foreach (KeyValuePair pair in reader) 830 | { 831 | if (pair.Key == "$type" || pair.Key == "$schema") continue; 832 | 833 | List rows = (List)pair.Value; 834 | if (rows == null) continue; 835 | 836 | DataTable dt = ds.Tables[pair.Key]; 837 | ReadDataTable(rows, dt); 838 | } 839 | 840 | ds.EndInit(); 841 | 842 | return ds; 843 | } 844 | 845 | private void ReadSchema(Dictionary reader, DataSet ds, Dictionary globalTypes) 846 | { 847 | var schema = reader["$schema"]; 848 | 849 | if (schema is string) 850 | { 851 | TextReader tr = new StringReader((string)schema); 852 | ds.ReadXmlSchema(tr); 853 | } 854 | else 855 | { 856 | DatasetSchema ms = (DatasetSchema)ParseDictionary((Dictionary)schema, globalTypes, typeof(DatasetSchema), null); 857 | ds.DataSetName = ms.Name; 858 | for (int i = 0; i < ms.Info.Count; i += 3) 859 | { 860 | if (ds.Tables.Contains(ms.Info[i]) == false) 861 | ds.Tables.Add(ms.Info[i]); 862 | ds.Tables[ms.Info[i]].Columns.Add(ms.Info[i + 1], Type.GetType(ms.Info[i + 2])); 863 | } 864 | } 865 | } 866 | 867 | private void ReadDataTable(List rows, DataTable dt) 868 | { 869 | dt.BeginInit(); 870 | dt.BeginLoadData(); 871 | List guidcols = new List(); 872 | List datecol = new List(); 873 | 874 | foreach (DataColumn c in dt.Columns) 875 | { 876 | if (c.DataType == typeof(Guid) || c.DataType == typeof(Guid?)) 877 | guidcols.Add(c.Ordinal); 878 | if (_params.UseUTCDateTime && (c.DataType == typeof(DateTime) || c.DataType == typeof(DateTime?))) 879 | datecol.Add(c.Ordinal); 880 | } 881 | 882 | foreach (List row in rows) 883 | { 884 | object[] v = new object[row.Count]; 885 | row.CopyTo(v, 0); 886 | foreach (int i in guidcols) 887 | { 888 | string s = (string)v[i]; 889 | if (s != null && s.Length < 36) 890 | v[i] = new Guid(Convert.FromBase64String(s)); 891 | } 892 | if (_params.UseUTCDateTime) 893 | { 894 | foreach (int i in datecol) 895 | { 896 | string s = (string)v[i]; 897 | if (s != null) 898 | v[i] = CreateDateTime(s); 899 | } 900 | } 901 | dt.Rows.Add(v); 902 | } 903 | 904 | dt.EndLoadData(); 905 | dt.EndInit(); 906 | } 907 | 908 | DataTable CreateDataTable(Dictionary reader, Dictionary globalTypes) 909 | { 910 | var dt = new DataTable(); 911 | 912 | // read dataset schema here 913 | var schema = reader["$schema"]; 914 | 915 | if (schema is string) 916 | { 917 | TextReader tr = new StringReader((string)schema); 918 | dt.ReadXmlSchema(tr); 919 | } 920 | else 921 | { 922 | var ms = (DatasetSchema)this.ParseDictionary((Dictionary)schema, globalTypes, typeof(DatasetSchema), null); 923 | dt.TableName = ms.Info[0]; 924 | for (int i = 0; i < ms.Info.Count; i += 3) 925 | { 926 | dt.Columns.Add(ms.Info[i + 1], Type.GetType(ms.Info[i + 2])); 927 | } 928 | } 929 | 930 | foreach (var pair in reader) 931 | { 932 | if (pair.Key == "$type" || pair.Key == "$schema") 933 | continue; 934 | 935 | var rows = (List)pair.Value; 936 | if (rows == null) 937 | continue; 938 | 939 | if (!dt.TableName.Equals(pair.Key, StringComparison.InvariantCultureIgnoreCase)) 940 | continue; 941 | 942 | ReadDataTable(rows, dt); 943 | } 944 | 945 | return dt; 946 | } 947 | #endif 948 | #endregion 949 | } 950 | 951 | } 952 | 953 | namespace fastJSON 954 | { 955 | /// 956 | /// This class encodes and decodes JSON strings. 957 | /// Spec. details, see http://www.json.org/ 958 | /// 959 | internal sealed class JsonParser 960 | { 961 | enum Token 962 | { 963 | None = -1, // Used to denote no Lookahead available 964 | Curly_Open, 965 | Curly_Close, 966 | Squared_Open, 967 | Squared_Close, 968 | Colon, 969 | Comma, 970 | String, 971 | Number, 972 | True, 973 | False, 974 | Null 975 | } 976 | 977 | readonly char[] json; 978 | readonly StringBuilder s = new StringBuilder(); 979 | Token lookAheadToken = Token.None; 980 | int index; 981 | bool _ignorecase = false; 982 | 983 | 984 | internal JsonParser(string json, bool ignorecase) 985 | { 986 | this.json = json.ToCharArray(); 987 | _ignorecase = ignorecase; 988 | } 989 | 990 | public object Decode() 991 | { 992 | return ParseValue(); 993 | } 994 | 995 | private Dictionary ParseObject() 996 | { 997 | Dictionary table = new Dictionary(); 998 | 999 | ConsumeToken(); // { 1000 | 1001 | while (true) 1002 | { 1003 | switch (LookAhead()) 1004 | { 1005 | 1006 | case Token.Comma: 1007 | ConsumeToken(); 1008 | break; 1009 | 1010 | case Token.Curly_Close: 1011 | ConsumeToken(); 1012 | return table; 1013 | 1014 | default: 1015 | { 1016 | 1017 | // name 1018 | string name = ParseString(); 1019 | if (_ignorecase) 1020 | name = name.ToLower(); 1021 | 1022 | // : 1023 | if (NextToken() != Token.Colon) 1024 | { 1025 | throw new Exception("Expected colon at index " + index); 1026 | } 1027 | 1028 | // value 1029 | object value = ParseValue(); 1030 | 1031 | table[name] = value; 1032 | } 1033 | break; 1034 | } 1035 | } 1036 | } 1037 | 1038 | private List ParseArray() 1039 | { 1040 | List array = new List(); 1041 | ConsumeToken(); // [ 1042 | 1043 | while (true) 1044 | { 1045 | switch (LookAhead()) 1046 | { 1047 | 1048 | case Token.Comma: 1049 | ConsumeToken(); 1050 | break; 1051 | 1052 | case Token.Squared_Close: 1053 | ConsumeToken(); 1054 | return array; 1055 | 1056 | default: 1057 | array.Add(ParseValue()); 1058 | break; 1059 | } 1060 | } 1061 | } 1062 | 1063 | private object ParseValue() 1064 | { 1065 | switch (LookAhead()) 1066 | { 1067 | case Token.Number: 1068 | return ParseNumber(); 1069 | 1070 | case Token.String: 1071 | return ParseString(); 1072 | 1073 | case Token.Curly_Open: 1074 | return ParseObject(); 1075 | 1076 | case Token.Squared_Open: 1077 | return ParseArray(); 1078 | 1079 | case Token.True: 1080 | ConsumeToken(); 1081 | return true; 1082 | 1083 | case Token.False: 1084 | ConsumeToken(); 1085 | return false; 1086 | 1087 | case Token.Null: 1088 | ConsumeToken(); 1089 | return null; 1090 | } 1091 | 1092 | throw new Exception("Unrecognized token at index" + index); 1093 | } 1094 | 1095 | private string ParseString() 1096 | { 1097 | ConsumeToken(); // " 1098 | 1099 | s.Length = 0; 1100 | 1101 | int runIndex = -1; 1102 | 1103 | while (index < json.Length) 1104 | { 1105 | var c = json[index++]; 1106 | 1107 | if (c == '"') 1108 | { 1109 | if (runIndex != -1) 1110 | { 1111 | if (s.Length == 0) 1112 | return new string(json, runIndex, index - runIndex - 1); 1113 | 1114 | s.Append(json, runIndex, index - runIndex - 1); 1115 | } 1116 | return s.ToString(); 1117 | } 1118 | 1119 | if (c != '\\') 1120 | { 1121 | if (runIndex == -1) 1122 | runIndex = index - 1; 1123 | 1124 | continue; 1125 | } 1126 | 1127 | if (index == json.Length) break; 1128 | 1129 | if (runIndex != -1) 1130 | { 1131 | s.Append(json, runIndex, index - runIndex - 1); 1132 | runIndex = -1; 1133 | } 1134 | 1135 | switch (json[index++]) 1136 | { 1137 | case '"': 1138 | s.Append('"'); 1139 | break; 1140 | 1141 | case '\\': 1142 | s.Append('\\'); 1143 | break; 1144 | 1145 | case '/': 1146 | s.Append('/'); 1147 | break; 1148 | 1149 | case 'b': 1150 | s.Append('\b'); 1151 | break; 1152 | 1153 | case 'f': 1154 | s.Append('\f'); 1155 | break; 1156 | 1157 | case 'n': 1158 | s.Append('\n'); 1159 | break; 1160 | 1161 | case 'r': 1162 | s.Append('\r'); 1163 | break; 1164 | 1165 | case 't': 1166 | s.Append('\t'); 1167 | break; 1168 | 1169 | case 'u': 1170 | { 1171 | int remainingLength = json.Length - index; 1172 | if (remainingLength < 4) break; 1173 | 1174 | // parse the 32 bit hex into an integer codepoint 1175 | uint codePoint = ParseUnicode(json[index], json[index + 1], json[index + 2], json[index + 3]); 1176 | s.Append((char)codePoint); 1177 | 1178 | // skip 4 chars 1179 | index += 4; 1180 | } 1181 | break; 1182 | } 1183 | } 1184 | 1185 | throw new Exception("Unexpectedly reached end of string"); 1186 | } 1187 | 1188 | private uint ParseSingleChar(char c1, uint multipliyer) 1189 | { 1190 | uint p1 = 0; 1191 | if (c1 >= '0' && c1 <= '9') 1192 | p1 = (uint)(c1 - '0') * multipliyer; 1193 | else if (c1 >= 'A' && c1 <= 'F') 1194 | p1 = (uint)((c1 - 'A') + 10) * multipliyer; 1195 | else if (c1 >= 'a' && c1 <= 'f') 1196 | p1 = (uint)((c1 - 'a') + 10) * multipliyer; 1197 | return p1; 1198 | } 1199 | 1200 | private uint ParseUnicode(char c1, char c2, char c3, char c4) 1201 | { 1202 | uint p1 = ParseSingleChar(c1, 0x1000); 1203 | uint p2 = ParseSingleChar(c2, 0x100); 1204 | uint p3 = ParseSingleChar(c3, 0x10); 1205 | uint p4 = ParseSingleChar(c4, 1); 1206 | 1207 | return p1 + p2 + p3 + p4; 1208 | } 1209 | 1210 | private long CreateLong(string s) 1211 | { 1212 | long num = 0; 1213 | bool neg = false; 1214 | foreach (char cc in s) 1215 | { 1216 | if (cc == '-') 1217 | neg = true; 1218 | else if (cc == '+') 1219 | neg = false; 1220 | else 1221 | { 1222 | num *= 10; 1223 | num += (int)(cc - '0'); 1224 | } 1225 | } 1226 | 1227 | return neg ? -num : num; 1228 | } 1229 | 1230 | private object ParseNumber() 1231 | { 1232 | ConsumeToken(); 1233 | 1234 | // Need to start back one place because the first digit is also a token and would have been consumed 1235 | var startIndex = index - 1; 1236 | bool dec = false; 1237 | do 1238 | { 1239 | if (index == json.Length) 1240 | break; 1241 | var c = json[index]; 1242 | 1243 | if ((c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+' || c == 'e' || c == 'E') 1244 | { 1245 | if (c == '.' || c == 'e' || c == 'E') 1246 | dec = true; 1247 | if (++index == json.Length) 1248 | break; //throw new Exception("Unexpected end of string whilst parsing number"); 1249 | continue; 1250 | } 1251 | break; 1252 | } while (true); 1253 | 1254 | string s = new string(json, startIndex, index - startIndex); 1255 | if (dec) 1256 | return double.Parse(s,NumberFormatInfo.InvariantInfo); 1257 | return CreateLong(s); 1258 | } 1259 | 1260 | private Token LookAhead() 1261 | { 1262 | if (lookAheadToken != Token.None) return lookAheadToken; 1263 | 1264 | return lookAheadToken = NextTokenCore(); 1265 | } 1266 | 1267 | private void ConsumeToken() 1268 | { 1269 | lookAheadToken = Token.None; 1270 | } 1271 | 1272 | private Token NextToken() 1273 | { 1274 | var result = lookAheadToken != Token.None ? lookAheadToken : NextTokenCore(); 1275 | 1276 | lookAheadToken = Token.None; 1277 | 1278 | return result; 1279 | } 1280 | 1281 | private Token NextTokenCore() 1282 | { 1283 | char c; 1284 | 1285 | // Skip past whitespace 1286 | do 1287 | { 1288 | c = json[index]; 1289 | 1290 | if (c > ' ') break; 1291 | if (c != ' ' && c != '\t' && c != '\n' && c != '\r') break; 1292 | 1293 | } while (++index < json.Length); 1294 | 1295 | if (index == json.Length) 1296 | { 1297 | throw new Exception("Reached end of string unexpectedly"); 1298 | } 1299 | 1300 | c = json[index]; 1301 | 1302 | index++; 1303 | 1304 | //if (c >= '0' && c <= '9') 1305 | // return Token.Number; 1306 | 1307 | switch (c) 1308 | { 1309 | case '{': 1310 | return Token.Curly_Open; 1311 | 1312 | case '}': 1313 | return Token.Curly_Close; 1314 | 1315 | case '[': 1316 | return Token.Squared_Open; 1317 | 1318 | case ']': 1319 | return Token.Squared_Close; 1320 | 1321 | case ',': 1322 | return Token.Comma; 1323 | 1324 | case '"': 1325 | return Token.String; 1326 | 1327 | case '0': 1328 | case '1': 1329 | case '2': 1330 | case '3': 1331 | case '4': 1332 | case '5': 1333 | case '6': 1334 | case '7': 1335 | case '8': 1336 | case '9': 1337 | case '-': 1338 | case '+': 1339 | case '.': 1340 | return Token.Number; 1341 | 1342 | case ':': 1343 | return Token.Colon; 1344 | 1345 | case 'f': 1346 | if (json.Length - index >= 4 && 1347 | json[index + 0] == 'a' && 1348 | json[index + 1] == 'l' && 1349 | json[index + 2] == 's' && 1350 | json[index + 3] == 'e') 1351 | { 1352 | index += 4; 1353 | return Token.False; 1354 | } 1355 | break; 1356 | 1357 | case 't': 1358 | if (json.Length - index >= 3 && 1359 | json[index + 0] == 'r' && 1360 | json[index + 1] == 'u' && 1361 | json[index + 2] == 'e') 1362 | { 1363 | index += 3; 1364 | return Token.True; 1365 | } 1366 | break; 1367 | 1368 | case 'n': 1369 | if (json.Length - index >= 3 && 1370 | json[index + 0] == 'u' && 1371 | json[index + 1] == 'l' && 1372 | json[index + 2] == 'l') 1373 | { 1374 | index += 3; 1375 | return Token.Null; 1376 | } 1377 | break; 1378 | 1379 | } 1380 | 1381 | throw new Exception("Could not find token at index " + --index); 1382 | } 1383 | } 1384 | } 1385 | 1386 | namespace fastJSON 1387 | { 1388 | internal sealed class JSONSerializer 1389 | { 1390 | private StringBuilder _output = new StringBuilder(); 1391 | private StringBuilder _before = new StringBuilder(); 1392 | readonly int _MAX_DEPTH = 10; 1393 | int _current_depth = 0; 1394 | private Dictionary _globalTypes = new Dictionary(); 1395 | private JSONParameters _params; 1396 | private bool _useEscapedUnicode = false; 1397 | 1398 | internal JSONSerializer(JSONParameters param) 1399 | { 1400 | _params = param; 1401 | _useEscapedUnicode = _params.UseEscapedUnicode; 1402 | } 1403 | 1404 | internal string ConvertToJSON(object obj) 1405 | { 1406 | WriteValue(obj); 1407 | 1408 | string str = ""; 1409 | if (_params.UsingGlobalTypes && _globalTypes != null && _globalTypes.Count > 0) 1410 | { 1411 | StringBuilder sb = _before; 1412 | sb.Append("\"$types\":{"); 1413 | bool pendingSeparator = false; 1414 | foreach (var kv in _globalTypes) 1415 | { 1416 | if (pendingSeparator) sb.Append(','); 1417 | pendingSeparator = true; 1418 | sb.Append("\""); 1419 | sb.Append(kv.Key); 1420 | sb.Append("\":\""); 1421 | sb.Append(kv.Value); 1422 | sb.Append("\""); 1423 | } 1424 | sb.Append("},"); 1425 | sb.Append(_output.ToString()); 1426 | str = sb.ToString(); 1427 | } 1428 | else 1429 | str = _output.ToString(); 1430 | 1431 | return str; 1432 | } 1433 | 1434 | private void WriteValue(object obj) 1435 | { 1436 | if (obj == null || obj is DBNull) 1437 | _output.Append("null"); 1438 | 1439 | else if (obj is string || obj is char) 1440 | WriteString(obj.ToString()); 1441 | 1442 | else if (obj is Guid) 1443 | WriteGuid((Guid)obj); 1444 | 1445 | else if (obj is bool) 1446 | _output.Append(((bool)obj) ? "true" : "false"); // conform to standard 1447 | 1448 | else if ( 1449 | obj is int || obj is long || obj is double || 1450 | obj is decimal || obj is float || 1451 | obj is byte || obj is short || 1452 | obj is sbyte || obj is ushort || 1453 | obj is uint || obj is ulong 1454 | ) 1455 | _output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo)); 1456 | 1457 | else if (obj is DateTime) 1458 | WriteDateTime((DateTime)obj); 1459 | 1460 | else if (obj is IDictionary && obj.GetType().IsGenericType && obj.GetType().GetGenericArguments()[0] == typeof(string)) 1461 | WriteStringDictionary((IDictionary)obj); 1462 | 1463 | else if (obj is IDictionary) 1464 | WriteDictionary((IDictionary)obj); 1465 | #if !SILVERLIGHT 1466 | else if (obj is DataSet) 1467 | WriteDataset((DataSet)obj); 1468 | 1469 | else if (obj is DataTable) 1470 | this.WriteDataTable((DataTable)obj); 1471 | #endif 1472 | else if (obj is byte[]) 1473 | WriteBytes((byte[])obj); 1474 | 1475 | else if (obj is Array || obj is IList || obj is ICollection) 1476 | WriteArray((IEnumerable)obj); 1477 | 1478 | else if (obj is Enum) 1479 | WriteEnum((Enum)obj); 1480 | 1481 | #if CUSTOMTYPE 1482 | else if (JSON.Instance.IsTypeRegistered(obj.GetType())) 1483 | WriteCustom(obj); 1484 | #endif 1485 | else 1486 | WriteObject(obj); 1487 | } 1488 | 1489 | #if CUSTOMTYPE 1490 | private void WriteCustom(object obj) 1491 | { 1492 | Serialize s; 1493 | JSON.Instance._customSerializer.TryGetValue(obj.GetType(), out s); 1494 | WriteStringFast(s(obj)); 1495 | } 1496 | #endif 1497 | 1498 | private void WriteEnum(Enum e) 1499 | { 1500 | // TODO : optimize enum write 1501 | WriteStringFast(e.ToString()); 1502 | } 1503 | 1504 | private void WriteGuid(Guid g) 1505 | { 1506 | if (_params.UseFastGuid == false) 1507 | WriteStringFast(g.ToString()); 1508 | else 1509 | WriteBytes(g.ToByteArray()); 1510 | } 1511 | 1512 | private void WriteBytes(byte[] bytes) 1513 | { 1514 | #if !SILVERLIGHT 1515 | WriteStringFast(Convert.ToBase64String(bytes, 0, bytes.Length, Base64FormattingOptions.None)); 1516 | #else 1517 | WriteStringFast(Convert.ToBase64String(bytes, 0, bytes.Length)); 1518 | #endif 1519 | } 1520 | 1521 | private void WriteDateTime(DateTime dateTime) 1522 | { 1523 | // datetime format standard : yyyy-MM-dd HH:mm:ss 1524 | DateTime dt = dateTime; 1525 | if (_params.UseUTCDateTime) 1526 | dt = dateTime.ToUniversalTime(); 1527 | 1528 | _output.Append("\""); 1529 | _output.Append(dt.Year.ToString("0000", NumberFormatInfo.InvariantInfo)); 1530 | _output.Append("-"); 1531 | _output.Append(dt.Month.ToString("00", NumberFormatInfo.InvariantInfo)); 1532 | _output.Append("-"); 1533 | _output.Append(dt.Day.ToString("00", NumberFormatInfo.InvariantInfo)); 1534 | _output.Append(" "); 1535 | _output.Append(dt.Hour.ToString("00", NumberFormatInfo.InvariantInfo)); 1536 | _output.Append(":"); 1537 | _output.Append(dt.Minute.ToString("00", NumberFormatInfo.InvariantInfo)); 1538 | _output.Append(":"); 1539 | _output.Append(dt.Second.ToString("00", NumberFormatInfo.InvariantInfo)); 1540 | 1541 | if (_params.UseUTCDateTime) 1542 | _output.Append("Z"); 1543 | 1544 | _output.Append("\""); 1545 | } 1546 | 1547 | #if !SILVERLIGHT 1548 | private DatasetSchema GetSchema(DataTable ds) 1549 | { 1550 | if (ds == null) return null; 1551 | 1552 | DatasetSchema m = new DatasetSchema(); 1553 | m.Info = new List(); 1554 | m.Name = ds.TableName; 1555 | 1556 | foreach (DataColumn c in ds.Columns) 1557 | { 1558 | m.Info.Add(ds.TableName); 1559 | m.Info.Add(c.ColumnName); 1560 | m.Info.Add(c.DataType.ToString()); 1561 | } 1562 | // FEATURE : serialize relations and constraints here 1563 | 1564 | return m; 1565 | } 1566 | 1567 | private DatasetSchema GetSchema(DataSet ds) 1568 | { 1569 | if (ds == null) return null; 1570 | 1571 | DatasetSchema m = new DatasetSchema(); 1572 | m.Info = new List(); 1573 | m.Name = ds.DataSetName; 1574 | 1575 | foreach (DataTable t in ds.Tables) 1576 | { 1577 | foreach (DataColumn c in t.Columns) 1578 | { 1579 | m.Info.Add(t.TableName); 1580 | m.Info.Add(c.ColumnName); 1581 | m.Info.Add(c.DataType.ToString()); 1582 | } 1583 | } 1584 | // FEATURE : serialize relations and constraints here 1585 | 1586 | return m; 1587 | } 1588 | 1589 | private string GetXmlSchema(DataTable dt) 1590 | { 1591 | using (var writer = new StringWriter()) 1592 | { 1593 | dt.WriteXmlSchema(writer); 1594 | return dt.ToString(); 1595 | } 1596 | } 1597 | 1598 | private void WriteDataset(DataSet ds) 1599 | { 1600 | _output.Append('{'); 1601 | if (_params.UseExtensions) 1602 | { 1603 | WritePair("$schema", _params.UseOptimizedDatasetSchema ? (object)GetSchema(ds) : ds.GetXmlSchema()); 1604 | _output.Append(','); 1605 | } 1606 | bool tablesep = false; 1607 | foreach (DataTable table in ds.Tables) 1608 | { 1609 | if (tablesep) _output.Append(","); 1610 | tablesep = true; 1611 | WriteDataTableData(table); 1612 | } 1613 | // end dataset 1614 | _output.Append('}'); 1615 | } 1616 | 1617 | private void WriteDataTableData(DataTable table) 1618 | { 1619 | _output.Append('\"'); 1620 | _output.Append(table.TableName); 1621 | _output.Append("\":["); 1622 | DataColumnCollection cols = table.Columns; 1623 | bool rowseparator = false; 1624 | foreach (DataRow row in table.Rows) 1625 | { 1626 | if (rowseparator) _output.Append(","); 1627 | rowseparator = true; 1628 | _output.Append('['); 1629 | 1630 | bool pendingSeperator = false; 1631 | foreach (DataColumn column in cols) 1632 | { 1633 | if (pendingSeperator) _output.Append(','); 1634 | WriteValue(row[column]); 1635 | pendingSeperator = true; 1636 | } 1637 | _output.Append(']'); 1638 | } 1639 | 1640 | _output.Append(']'); 1641 | } 1642 | 1643 | void WriteDataTable(DataTable dt) 1644 | { 1645 | this._output.Append('{'); 1646 | if (_params.UseExtensions) 1647 | { 1648 | this.WritePair("$schema", _params.UseOptimizedDatasetSchema ? (object)this.GetSchema(dt) : this.GetXmlSchema(dt)); 1649 | this._output.Append(','); 1650 | } 1651 | 1652 | WriteDataTableData(dt); 1653 | 1654 | // end datatable 1655 | this._output.Append('}'); 1656 | } 1657 | #endif 1658 | 1659 | bool _TypesWritten = false; 1660 | private void WriteObject(object obj) 1661 | { 1662 | if (_params.UsingGlobalTypes == false) 1663 | _output.Append('{'); 1664 | else 1665 | { 1666 | if (_TypesWritten == false) 1667 | { 1668 | _output.Append("{"); 1669 | _before = _output; 1670 | _output = new StringBuilder(); 1671 | } 1672 | else 1673 | _output.Append("{"); 1674 | } 1675 | _TypesWritten = true; 1676 | _current_depth++; 1677 | if (_current_depth > _MAX_DEPTH) 1678 | throw new Exception("Serializer encountered maximum depth of " + _MAX_DEPTH); 1679 | 1680 | 1681 | Dictionary map = new Dictionary(); 1682 | Type t = obj.GetType(); 1683 | bool append = false; 1684 | if (_params.UseExtensions) 1685 | { 1686 | if (_params.UsingGlobalTypes == false) 1687 | WritePairFast("$type", Reflection.Instance.GetTypeAssemblyName(t)); 1688 | else 1689 | { 1690 | int dt = 0; 1691 | string ct = Reflection.Instance.GetTypeAssemblyName(t); 1692 | if (_globalTypes.TryGetValue(ct, out dt) == false) 1693 | { 1694 | dt = _globalTypes.Count + 1; 1695 | _globalTypes.Add(ct, dt); 1696 | } 1697 | WritePairFast("$type", dt.ToString()); 1698 | } 1699 | append = true; 1700 | } 1701 | 1702 | List g = Reflection.Instance.GetGetters(t); 1703 | int c = g.Count; 1704 | int i = c; 1705 | if (_params.UseExtensions) // count $type as a property 1706 | i++; 1707 | foreach (var p in g) 1708 | { 1709 | i--; 1710 | if (append && i > 0) 1711 | _output.Append(','); 1712 | object o = p.Getter(obj); 1713 | if ((o == null || o is DBNull) && _params.SerializeNullValues == false) 1714 | append = false; 1715 | else 1716 | { 1717 | if (i == 0 && c > 1) // last non null 1718 | _output.Append(","); 1719 | WritePair(p.Name, o); 1720 | if (o != null && _params.UseExtensions) 1721 | { 1722 | Type tt = o.GetType(); 1723 | if (tt == typeof(System.Object)) 1724 | map.Add(p.Name, tt.ToString()); 1725 | } 1726 | append = true; 1727 | } 1728 | } 1729 | if (map.Count > 0 && _params.UseExtensions) 1730 | { 1731 | _output.Append(",\"$map\":"); 1732 | WriteStringDictionary(map); 1733 | } 1734 | _current_depth--; 1735 | _output.Append('}'); 1736 | _current_depth--; 1737 | } 1738 | 1739 | private void WritePairFast(string name, string value) 1740 | { 1741 | if ((value == null) && _params.SerializeNullValues == false) 1742 | return; 1743 | WriteStringFast(name); 1744 | 1745 | _output.Append(':'); 1746 | 1747 | WriteStringFast(value); 1748 | } 1749 | 1750 | private void WritePair(string name, object value) 1751 | { 1752 | if ((value == null || value is DBNull) && _params.SerializeNullValues == false) 1753 | return; 1754 | WriteStringFast(name); 1755 | 1756 | _output.Append(':'); 1757 | 1758 | WriteValue(value); 1759 | } 1760 | 1761 | private void WriteArray(IEnumerable array) 1762 | { 1763 | _output.Append('['); 1764 | 1765 | bool pendingSeperator = false; 1766 | 1767 | foreach (object obj in array) 1768 | { 1769 | if (pendingSeperator) _output.Append(','); 1770 | 1771 | WriteValue(obj); 1772 | 1773 | pendingSeperator = true; 1774 | } 1775 | _output.Append(']'); 1776 | } 1777 | 1778 | private void WriteStringDictionary(IDictionary dic) 1779 | { 1780 | _output.Append('{'); 1781 | 1782 | bool pendingSeparator = false; 1783 | 1784 | foreach (DictionaryEntry entry in dic) 1785 | { 1786 | if (pendingSeparator) _output.Append(','); 1787 | 1788 | WritePair((string)entry.Key, entry.Value); 1789 | 1790 | pendingSeparator = true; 1791 | } 1792 | _output.Append('}'); 1793 | } 1794 | 1795 | private void WriteDictionary(IDictionary dic) 1796 | { 1797 | _output.Append('['); 1798 | 1799 | bool pendingSeparator = false; 1800 | 1801 | foreach (DictionaryEntry entry in dic) 1802 | { 1803 | if (pendingSeparator) _output.Append(','); 1804 | _output.Append('{'); 1805 | WritePair("k", entry.Key); 1806 | _output.Append(","); 1807 | WritePair("v", entry.Value); 1808 | _output.Append('}'); 1809 | 1810 | pendingSeparator = true; 1811 | } 1812 | _output.Append(']'); 1813 | } 1814 | 1815 | private void WriteStringFast(string s) 1816 | { 1817 | _output.Append('\"'); 1818 | _output.Append(s); 1819 | _output.Append('\"'); 1820 | } 1821 | 1822 | private void WriteString(string s) 1823 | { 1824 | _output.Append('\"'); 1825 | 1826 | int runIndex = -1; 1827 | 1828 | for (var index = 0; index < s.Length; ++index) 1829 | { 1830 | var c = s[index]; 1831 | 1832 | if (_useEscapedUnicode) 1833 | { 1834 | if (c >= ' ' && c < 128 && c != '\"' && c != '\\') 1835 | { 1836 | if (runIndex == -1) 1837 | runIndex = index; 1838 | 1839 | continue; 1840 | } 1841 | } 1842 | else 1843 | { 1844 | if (c != '\t' && c != '\n' && c != '\r' && c != '\"' && c != '\\')// && c != ':' && c!=',') 1845 | { 1846 | if (runIndex == -1) 1847 | runIndex = index; 1848 | 1849 | continue; 1850 | } 1851 | } 1852 | 1853 | if (runIndex != -1) 1854 | { 1855 | _output.Append(s, runIndex, index - runIndex); 1856 | runIndex = -1; 1857 | } 1858 | 1859 | switch (c) 1860 | { 1861 | case '\t': _output.Append("\\t"); break; 1862 | case '\r': _output.Append("\\r"); break; 1863 | case '\n': _output.Append("\\n"); break; 1864 | case '"': 1865 | case '\\': _output.Append('\\'); _output.Append(c); break; 1866 | default: 1867 | if (_useEscapedUnicode) 1868 | { 1869 | _output.Append("\\u"); 1870 | _output.Append(((int)c).ToString("X4", NumberFormatInfo.InvariantInfo)); 1871 | } 1872 | else 1873 | _output.Append(c); 1874 | 1875 | break; 1876 | } 1877 | } 1878 | 1879 | if (runIndex != -1) 1880 | _output.Append(s, runIndex, s.Length - runIndex); 1881 | 1882 | 1883 | _output.Append('\"'); 1884 | } 1885 | } 1886 | } 1887 | 1888 | namespace fastJSON 1889 | { 1890 | internal struct Getters 1891 | { 1892 | public string Name; 1893 | public Reflection.GenericGetter Getter; 1894 | public Type propertyType; 1895 | } 1896 | 1897 | internal sealed class Reflection 1898 | { 1899 | public readonly static Reflection Instance = new Reflection(); 1900 | private Reflection() 1901 | { 1902 | } 1903 | 1904 | public bool ShowReadOnlyProperties = false; 1905 | internal delegate object GenericSetter(object target, object value); 1906 | internal delegate object GenericGetter(object obj); 1907 | private delegate object CreateObject(); 1908 | 1909 | private SafeDictionary _tyname = new SafeDictionary(); 1910 | private SafeDictionary _typecache = new SafeDictionary(); 1911 | private SafeDictionary _constrcache = new SafeDictionary(); 1912 | private SafeDictionary> _getterscache = new SafeDictionary>(); 1913 | 1914 | #region [ PROPERTY GET SET ] 1915 | internal string GetTypeAssemblyName(Type t) 1916 | { 1917 | string val = ""; 1918 | if (_tyname.TryGetValue(t, out val)) 1919 | return val; 1920 | else 1921 | { 1922 | string s = t.AssemblyQualifiedName; 1923 | _tyname.Add(t, s); 1924 | return s; 1925 | } 1926 | } 1927 | 1928 | internal Type GetTypeFromCache(string typename) 1929 | { 1930 | Type val = null; 1931 | if (_typecache.TryGetValue(typename, out val)) 1932 | return val; 1933 | else 1934 | { 1935 | Type t = Type.GetType(typename); 1936 | _typecache.Add(typename, t); 1937 | return t; 1938 | } 1939 | } 1940 | 1941 | internal object FastCreateInstance(Type objtype) 1942 | { 1943 | try 1944 | { 1945 | CreateObject c = null; 1946 | if (_constrcache.TryGetValue(objtype, out c)) 1947 | { 1948 | return c(); 1949 | } 1950 | else 1951 | { 1952 | if (objtype.IsClass) 1953 | { 1954 | DynamicMethod dynMethod = new DynamicMethod("_", objtype, null); 1955 | ILGenerator ilGen = dynMethod.GetILGenerator(); 1956 | ilGen.Emit(OpCodes.Newobj, objtype.GetConstructor(Type.EmptyTypes)); 1957 | ilGen.Emit(OpCodes.Ret); 1958 | c = (CreateObject)dynMethod.CreateDelegate(typeof(CreateObject)); 1959 | _constrcache.Add(objtype, c); 1960 | } 1961 | else // structs 1962 | { 1963 | DynamicMethod dynMethod = new DynamicMethod("_", 1964 | MethodAttributes.Public | MethodAttributes.Static, 1965 | CallingConventions.Standard, 1966 | typeof(object), 1967 | null, 1968 | objtype, false); 1969 | ILGenerator ilGen = dynMethod.GetILGenerator(); 1970 | var lv = ilGen.DeclareLocal(objtype); 1971 | ilGen.Emit(OpCodes.Ldloca_S, lv); 1972 | ilGen.Emit(OpCodes.Initobj, objtype); 1973 | ilGen.Emit(OpCodes.Ldloc_0); 1974 | ilGen.Emit(OpCodes.Box, objtype); 1975 | ilGen.Emit(OpCodes.Ret); 1976 | c = (CreateObject)dynMethod.CreateDelegate(typeof(CreateObject)); 1977 | _constrcache.Add(objtype, c); 1978 | } 1979 | return c(); 1980 | } 1981 | } 1982 | catch (Exception exc) 1983 | { 1984 | throw new Exception(string.Format("Failed to fast create instance for type '{0}' from assemebly '{1}'", 1985 | objtype.FullName, objtype.AssemblyQualifiedName), exc); 1986 | } 1987 | } 1988 | 1989 | internal static GenericSetter CreateSetField(Type type, FieldInfo fieldInfo) 1990 | { 1991 | Type[] arguments = new Type[2]; 1992 | arguments[0] = arguments[1] = typeof(object); 1993 | 1994 | DynamicMethod dynamicSet = new DynamicMethod("_", typeof(object), arguments, type, true); 1995 | ILGenerator il = dynamicSet.GetILGenerator(); 1996 | 1997 | if (!type.IsClass) // structs 1998 | { 1999 | var lv = il.DeclareLocal(type); 2000 | il.Emit(OpCodes.Ldarg_0); 2001 | il.Emit(OpCodes.Unbox_Any, type); 2002 | il.Emit(OpCodes.Stloc_0); 2003 | il.Emit(OpCodes.Ldloca_S, lv); 2004 | il.Emit(OpCodes.Ldarg_1); 2005 | if (fieldInfo.FieldType.IsClass) 2006 | il.Emit(OpCodes.Castclass, fieldInfo.FieldType); 2007 | else 2008 | il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType); 2009 | il.Emit(OpCodes.Stfld, fieldInfo); 2010 | il.Emit(OpCodes.Ldloc_0); 2011 | il.Emit(OpCodes.Box, type); 2012 | il.Emit(OpCodes.Ret); 2013 | } 2014 | else 2015 | { 2016 | il.Emit(OpCodes.Ldarg_0); 2017 | il.Emit(OpCodes.Ldarg_1); 2018 | if (fieldInfo.FieldType.IsValueType) 2019 | il.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType); 2020 | il.Emit(OpCodes.Stfld, fieldInfo); 2021 | il.Emit(OpCodes.Ldarg_0); 2022 | il.Emit(OpCodes.Ret); 2023 | } 2024 | return (GenericSetter)dynamicSet.CreateDelegate(typeof(GenericSetter)); 2025 | } 2026 | 2027 | internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyInfo) 2028 | { 2029 | MethodInfo setMethod = propertyInfo.GetSetMethod(); 2030 | if (setMethod == null) 2031 | return null; 2032 | 2033 | Type[] arguments = new Type[2]; 2034 | arguments[0] = arguments[1] = typeof(object); 2035 | 2036 | DynamicMethod setter = new DynamicMethod("_", typeof(object), arguments); 2037 | ILGenerator il = setter.GetILGenerator(); 2038 | 2039 | if (!type.IsClass) // structs 2040 | { 2041 | var lv = il.DeclareLocal(type); 2042 | il.Emit(OpCodes.Ldarg_0); 2043 | il.Emit(OpCodes.Unbox_Any, type); 2044 | il.Emit(OpCodes.Stloc_0); 2045 | il.Emit(OpCodes.Ldloca_S, lv); 2046 | il.Emit(OpCodes.Ldarg_1); 2047 | if (propertyInfo.PropertyType.IsClass) 2048 | il.Emit(OpCodes.Castclass, propertyInfo.PropertyType); 2049 | else 2050 | il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); 2051 | il.EmitCall(OpCodes.Call, setMethod, null); 2052 | il.Emit(OpCodes.Ldloc_0); 2053 | il.Emit(OpCodes.Box, type); 2054 | } 2055 | else 2056 | { 2057 | il.Emit(OpCodes.Ldarg_0); 2058 | il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType); 2059 | il.Emit(OpCodes.Ldarg_1); 2060 | if (propertyInfo.PropertyType.IsClass) 2061 | il.Emit(OpCodes.Castclass, propertyInfo.PropertyType); 2062 | else 2063 | il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); 2064 | il.EmitCall(OpCodes.Callvirt, setMethod, null); 2065 | il.Emit(OpCodes.Ldarg_0); 2066 | } 2067 | 2068 | il.Emit(OpCodes.Ret); 2069 | 2070 | return (GenericSetter)setter.CreateDelegate(typeof(GenericSetter)); 2071 | } 2072 | 2073 | internal static GenericGetter CreateGetField(Type type, FieldInfo fieldInfo) 2074 | { 2075 | DynamicMethod dynamicGet = new DynamicMethod("_", typeof(object), new Type[] { typeof(object) }, type, true); 2076 | ILGenerator il = dynamicGet.GetILGenerator(); 2077 | 2078 | if (!type.IsClass) // structs 2079 | { 2080 | var lv = il.DeclareLocal(type); 2081 | il.Emit(OpCodes.Ldarg_0); 2082 | il.Emit(OpCodes.Unbox_Any, type); 2083 | il.Emit(OpCodes.Stloc_0); 2084 | il.Emit(OpCodes.Ldloca_S, lv); 2085 | il.Emit(OpCodes.Ldfld, fieldInfo); 2086 | if (fieldInfo.FieldType.IsValueType) 2087 | il.Emit(OpCodes.Box, fieldInfo.FieldType); 2088 | } 2089 | else 2090 | { 2091 | il.Emit(OpCodes.Ldarg_0); 2092 | il.Emit(OpCodes.Ldfld, fieldInfo); 2093 | if (fieldInfo.FieldType.IsValueType) 2094 | il.Emit(OpCodes.Box, fieldInfo.FieldType); 2095 | } 2096 | 2097 | il.Emit(OpCodes.Ret); 2098 | 2099 | return (GenericGetter)dynamicGet.CreateDelegate(typeof(GenericGetter)); 2100 | } 2101 | 2102 | internal static GenericGetter CreateGetMethod(Type type, PropertyInfo propertyInfo) 2103 | { 2104 | MethodInfo getMethod = propertyInfo.GetGetMethod(); 2105 | if (getMethod == null) 2106 | return null; 2107 | 2108 | Type[] arguments = new Type[1]; 2109 | arguments[0] = typeof(object); 2110 | 2111 | DynamicMethod getter = new DynamicMethod("_", typeof(object), arguments, type); 2112 | ILGenerator il = getter.GetILGenerator(); 2113 | 2114 | if (!type.IsClass) // structs 2115 | { 2116 | var lv = il.DeclareLocal(type); 2117 | il.Emit(OpCodes.Ldarg_0); 2118 | il.Emit(OpCodes.Unbox_Any, type); 2119 | il.Emit(OpCodes.Stloc_0); 2120 | il.Emit(OpCodes.Ldloca_S, lv); 2121 | il.EmitCall(OpCodes.Call, getMethod, null); 2122 | if (propertyInfo.PropertyType.IsValueType) 2123 | il.Emit(OpCodes.Box, propertyInfo.PropertyType); 2124 | } 2125 | else 2126 | { 2127 | il.Emit(OpCodes.Ldarg_0); 2128 | il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType); 2129 | il.EmitCall(OpCodes.Callvirt, getMethod, null); 2130 | if (propertyInfo.PropertyType.IsValueType) 2131 | il.Emit(OpCodes.Box, propertyInfo.PropertyType); 2132 | } 2133 | 2134 | il.Emit(OpCodes.Ret); 2135 | 2136 | return (GenericGetter)getter.CreateDelegate(typeof(GenericGetter)); 2137 | } 2138 | 2139 | internal List GetGetters(Type type) 2140 | { 2141 | List val = null; 2142 | if (_getterscache.TryGetValue(type, out val)) 2143 | return val; 2144 | 2145 | PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); 2146 | List getters = new List(); 2147 | foreach (PropertyInfo p in props) 2148 | { 2149 | if (!p.CanWrite && ShowReadOnlyProperties == false) continue; 2150 | 2151 | object[] att = p.GetCustomAttributes(typeof(System.Xml.Serialization.XmlIgnoreAttribute), false); 2152 | if (att != null && att.Length > 0) 2153 | continue; 2154 | 2155 | GenericGetter g = CreateGetMethod(type, p); 2156 | if (g != null) 2157 | { 2158 | Getters gg = new Getters(); 2159 | gg.Name = p.Name; 2160 | gg.Getter = g; 2161 | gg.propertyType = p.PropertyType; 2162 | getters.Add(gg); 2163 | } 2164 | } 2165 | 2166 | FieldInfo[] fi = type.GetFields(BindingFlags.Instance | BindingFlags.Public); 2167 | foreach (var f in fi) 2168 | { 2169 | object[] att = f.GetCustomAttributes(typeof(System.Xml.Serialization.XmlIgnoreAttribute), false); 2170 | if (att != null && att.Length > 0) 2171 | continue; 2172 | 2173 | GenericGetter g = CreateGetField(type, f); 2174 | if (g != null) 2175 | { 2176 | Getters gg = new Getters(); 2177 | gg.Name = f.Name; 2178 | gg.Getter = g; 2179 | gg.propertyType = f.FieldType; 2180 | getters.Add(gg); 2181 | } 2182 | } 2183 | 2184 | _getterscache.Add(type, getters); 2185 | return getters; 2186 | } 2187 | 2188 | #endregion 2189 | } 2190 | } 2191 | 2192 | namespace fastJSON 2193 | { 2194 | internal sealed class SafeDictionary 2195 | { 2196 | private readonly object _Padlock = new object(); 2197 | private readonly Dictionary _Dictionary; 2198 | 2199 | public SafeDictionary(int capacity) 2200 | { 2201 | _Dictionary = new Dictionary(capacity); 2202 | } 2203 | 2204 | public SafeDictionary() 2205 | { 2206 | _Dictionary = new Dictionary(); 2207 | } 2208 | 2209 | public bool TryGetValue(TKey key, out TValue value) 2210 | { 2211 | lock (_Padlock) 2212 | return _Dictionary.TryGetValue(key, out value); 2213 | } 2214 | 2215 | public TValue this[TKey key] 2216 | { 2217 | get 2218 | { 2219 | lock (_Padlock) 2220 | return _Dictionary[key]; 2221 | } 2222 | set 2223 | { 2224 | lock (_Padlock) 2225 | _Dictionary[key] = value; 2226 | } 2227 | } 2228 | 2229 | public void Add(TKey key, TValue value) 2230 | { 2231 | lock (_Padlock) 2232 | { 2233 | if (_Dictionary.ContainsKey(key) == false) 2234 | _Dictionary.Add(key, value); 2235 | } 2236 | } 2237 | } 2238 | } 2239 | -------------------------------------------------------------------------------- /ExportJson/lib/dotNetFx45_Full_setup.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/ExportJson/lib/dotNetFx45_Full_setup.exe -------------------------------------------------------------------------------- /ExportJson/res/ConfigLoadTemplate.cs: -------------------------------------------------------------------------------- 1 | //郭晓波 2 | using UnityEngine; 3 | using System.Collections; 4 | using HS.Base; 5 | 6 | public class ConfigLoad : HS_SingletonGameObject { 7 | 8 | private string textContent; 9 | 10 | private int fileCount = $fileCount$; 11 | 12 | public delegate void ConfigLoadProgress(float f); 13 | 14 | public event ConfigLoadProgress configLoadProgress; 15 | 16 | public IEnumerator LoadConfig () { 17 | 18 | $loadConfItem$ 19 | 20 | yield return true; 21 | } 22 | 23 | IEnumerator LoadData (string name) { 24 | 25 | string path = HS_Base.GetStreamingAssetsFilePath(name, "json"); 26 | 27 | WWW www = new WWW(path); 28 | yield return www; 29 | 30 | textContent = www.text; 31 | yield return true; 32 | } 33 | 34 | void Progress(int index) 35 | { 36 | if (configLoadProgress != null) 37 | { 38 | configLoadProgress((float)index / (float)fileCount); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ExportJson/res/ConfigTemplate.cs: -------------------------------------------------------------------------------- 1 | //郭晓波 2 | using UnityEngine; 3 | using System; 4 | using System.IO; 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | using HS.IO; 8 | using LitJson; 9 | 10 | 11 | public class $Template$Element 12 | { 13 | $FieldDefine$ 14 | public bool IsValidate = false; 15 | public $Template$Element() 16 | { 17 | $InitPrimaryField$ 18 | } 19 | }; 20 | 21 | 22 | public class $Template$Table 23 | { 24 | 25 | private $Template$Table() 26 | { 27 | _MapElements = new Dictionary(); 28 | _EmptyItem = new $Template$Element(); 29 | _VecAllElements = new List<$Template$Element>(); 30 | } 31 | private Dictionary _MapElements = null; 32 | private List<$Template$Element> _VecAllElements = null; 33 | private $Template$Element _EmptyItem = null; 34 | private static $Template$Table _SInstance = null; 35 | 36 | public static $Template$Table Instance 37 | { 38 | get 39 | { 40 | if( _SInstance != null ) 41 | return _SInstance; 42 | _SInstance = new $Template$Table(); 43 | return _SInstance; 44 | } 45 | } 46 | 47 | public $Template$Element GetElement(int key) 48 | { 49 | if( _MapElements.ContainsKey(key) ) 50 | return _MapElements[key]; 51 | return _EmptyItem; 52 | } 53 | 54 | public int GetElementCount() 55 | { 56 | return _MapElements.Count; 57 | } 58 | public bool HasElement(int key) 59 | { 60 | return _MapElements.ContainsKey(key); 61 | } 62 | 63 | public List<$Template$Element> GetAllElement(Predicate<$Template$Element> matchCB = null) 64 | { 65 | if( matchCB==null || _VecAllElements.Count == 0) 66 | return _VecAllElements; 67 | return _VecAllElements.FindAll(matchCB); 68 | } 69 | 70 | public bool Load() 71 | { 72 | 73 | string strTableContent = ""; 74 | if(HS_ByteRead.ReadCsvFile("$Template$.json", out strTableContent ) ) 75 | return LoadCsv( strTableContent ); 76 | byte[] binTableContent = null; 77 | if( !HS_ByteRead.ReadBinFile("$Template$.bin", out binTableContent ) ) 78 | { 79 | Debug.Log("配置文件[$Template$.bin]未找到"); 80 | return false; 81 | } 82 | return LoadBin(binTableContent); 83 | } 84 | 85 | 86 | public bool LoadBin(byte[] binContent) 87 | { 88 | _MapElements.Clear(); 89 | _VecAllElements.Clear(); 90 | int nCol, nRow; 91 | int readPos = 0; 92 | readPos += HS_ByteRead.ReadInt32Variant( binContent, readPos, out nCol ); 93 | readPos += HS_ByteRead.ReadInt32Variant( binContent, readPos, out nRow ); 94 | List vecLine = new List(nCol); 95 | List vecHeadType = new List(nCol); 96 | string tmpStr; 97 | int tmpInt; 98 | for( int i=0; i vecLine; 129 | vecLine = HS_ByteRead.readCsvLine( strContent, ref contentOffset ); 130 | if(vecLine.Count != $ColCount$) 131 | { 132 | Debug.Log("$Template$.json 中列数量与生成的代码不匹配!"); 133 | return false; 134 | } 135 | $CheckColName$ 136 | while(true) 137 | { 138 | vecLine = HS_ByteRead.readCsvLine( strContent, ref contentOffset ); 139 | if((int)vecLine.Count == 0 ) 140 | break; 141 | if((int)vecLine.Count != (int)$ColCount$) 142 | { 143 | return false; 144 | } 145 | $Template$Element member = new $Template$Element(); 146 | $ReadCsvColValue$ 147 | member.IsValidate = true; 148 | _VecAllElements.Add(member); 149 | _MapElements[member.$PrimaryKey$] = member; 150 | } 151 | return true; 152 | } 153 | 154 | public bool LoadJson(string strContent) 155 | { 156 | JsonData jsonData = JsonMapper.ToObject(strContent); 157 | for (int i = 0; i < jsonData.Count; ++i) 158 | { 159 | JsonData jd = jsonData[i]; 160 | if(jd.Keys.Count != $ColCount$) 161 | { 162 | Debug.Log("$Template$.json中列数量与生成的代码不匹配!"); 163 | return false; 164 | } 165 | 166 | $Template$Element member = new $Template$Element(); 167 | $ReadJsonColValue$ 168 | 169 | member.IsValidate = true; 170 | _VecAllElements.Add(member); 171 | _MapElements[member.$PrimaryKey$] = member; 172 | } 173 | return true; 174 | } 175 | }; 176 | -------------------------------------------------------------------------------- /ExportJson/res/josn_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/ExportJson/res/josn_icon.ico -------------------------------------------------------------------------------- /ExportJson/res/josn_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/b81af59ab1ec2517aef41c4afacb4019d5c55729/ExportJson/res/josn_icon.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Excel导出Json插件 2 | 作者:郭晓波 3 | 邮箱:Ambitiongxb@foxmail.com 4 | ## 普通格式 5 | Excel 插件 导出 Json 数据格式 6 | ------------------------------------------------------------------- 7 | ## 数据类型格式 8 | Excel格式如下: 9 | 文件保存格式:xxx_描述.xlsx 10 | 第一行:描述 11 | 第二行:类型 I->int | F->float | S->String | B->bool 12 | 第三行:字段名 13 | ------------------------------------------------------------------- 14 | # 安装包下载 15 | [下载网站](http://wanggan768q.github.io/ExportJson-for-Excel-2014/) 16 | 17 | [必须下载](https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/master/Download/Essential/vstor_redist.exe) 18 | [ExportJson 1.1.0.33 安装包下载](https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/master/Download/ExportJson_1_1_0_33.zip) 19 | [ExportJson 1.1.0.32 安装包下载](https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/master/Download/ExportJson_1_1_0_32.zip) 20 | [ExportJson 1.1.0.31 安装包下载](https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/master/Download/ExportJson_1_1_0_31.zip) 21 | [ExportJson 1.1.0.30 安装包下载](https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/master/Download/ExportJson_1_1_0_30.zip) 22 | [ExportJson 1.1.0.29 安装包下载](https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/master/Download/ExportJson_1_1_0_29.zip) 23 | [ExportJson 1.1.0.28 安装包下载](https://raw.githubusercontent.com/wanggan768q/ExportJson-for-Excel-2014/master/Download/ExportJson_1_1_0_28.zip) 24 | 25 | 26 | --------------------------------------------------------------------------------