Commit 8dec7eaa authored by oshima's avatar oshima

Excel⇒Adoc変換ツール

parent b57adfcb
■使い方
1.EcxelToAdocConverter.exeを起動
2.エクセルで任意の範囲を選択しコピー
3."Get AsciiDoc from Clipboad"をクリック
4.結果をAdocにコピペ
■更新履歴
==========================
2021/03/11 rev1
以下サイトを参考に、エクセルの表をAdoc表記に変換するツールを用意しました。
(参考)
[ExcelとかWordでクリップボードにコピーしたデータからAsciiDocの表に変換するツールをつくってみた(結合セル対応)]
https://qiita.com/kob58im/items/8c3c609b828afbc8fec2
==========================
2021/03/11 rev2 大島追記
・水平垂直の揃えに対応しました。
・デフォルト値を以下のようにしました。
  ・列の幅は自動調整
  

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.1000
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EcxelToAdocConverter", "EcxelToAdocConverter\EcxelToAdocConverter.csproj", "{36AA7526-71EF-4009-B21E-55A0FF4CFA12}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{36AA7526-71EF-4009-B21E-55A0FF4CFA12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{36AA7526-71EF-4009-B21E-55A0FF4CFA12}.Debug|Any CPU.Build.0 = Debug|Any CPU
{36AA7526-71EF-4009-B21E-55A0FF4CFA12}.Debug|x64.ActiveCfg = Debug|x64
{36AA7526-71EF-4009-B21E-55A0FF4CFA12}.Debug|x64.Build.0 = Debug|x64
{36AA7526-71EF-4009-B21E-55A0FF4CFA12}.Release|Any CPU.ActiveCfg = Release|Any CPU
{36AA7526-71EF-4009-B21E-55A0FF4CFA12}.Release|Any CPU.Build.0 = Release|Any CPU
{36AA7526-71EF-4009-B21E-55A0FF4CFA12}.Release|x64.ActiveCfg = Release|x64
{36AA7526-71EF-4009-B21E-55A0FF4CFA12}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0FA1ADE2-6079-4C87-8348-420742F0DD6D}
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{36AA7526-71EF-4009-B21E-55A0FF4CFA12}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>EcxelToAdocConverter</RootNamespace>
<AssemblyName>EcxelToAdocConverter</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ExcelToAdocConverter.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ExcelToAdocConverter.resx">
<DependentUpon>ExcelToAdocConverter.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
class SampleForm : Form
{
static readonly int ExpectedHeaderMaxLines = 20;
static readonly Regex rxTableBeginTag = new Regex(@"<table(?:\s)?[^>]*>", RegexOptions.Multiline | RegexOptions.IgnoreCase);
// 1 2 3 *?は最短マッチ o:pはMS office(word)対策
static readonly Regex rxTag = new Regex(@"<([a-z][a-z0-9]*|o:p)(|\s[^>]*)>|</([a-z][a-z0-9]*|o:p)>|<!--(?:.*?)-->", RegexOptions.Multiline | RegexOptions.IgnoreCase);
//static readonly Regex rxTag = new Regex(@"<([a-z][a-z0-9]*)(|\s[^>]*)>|</([a-z][a-z0-9]*)>|<!--(?:.*?)-->", RegexOptions.Multiline | RegexOptions.IgnoreCase);
TextBox txtAdoc;
SampleForm()
{
Text = "HTML table(Clipborad) to AsciiDoc";
ClientSize = new Size(700, 430);
var btn = new Button()
{
Size = new Size(280, 25),
Text = "Get AsciiDoc from Clipborad",
};
btn.Click += (s, e) => { ParseFromHtmlClipboard(); };
Controls.Add(btn);
var btnDbg = new Button()
{
Location = new Point(300, 0),
Size = new Size(220, 25),
Text = "Get HTML from Clipborad(開発者用)",
};
btnDbg.Click += (s, e) => { DumpHtmlClipboard(); };
Controls.Add(btnDbg);
txtAdoc = new TextBox()
{
Location = new Point(0, 30),
Size = new Size(700, 400),
Text = "",
Multiline = true,
WordWrap = false, // 折り返し表示をしない
ScrollBars = ScrollBars.Both,
};
Controls.Add(txtAdoc);
txtAdoc.KeyDown += (s, e) => { if (e.Control && e.KeyCode == Keys.A) { ((TextBox)s).SelectAll(); } };
Resize += (s, e) => { MyResize(); };
ResizeEnd += (s, e) => { MyResize(); };
}
void MyResize()
{
int h = ClientSize.Height - txtAdoc.Top;
if (h < 50) { h = 50; }
txtAdoc.Size = new Size(ClientSize.Width, h);
}
void ParseFromHtmlClipboard()
{
MemoryStream ms = GetHtmlClipboard();
if (ms != null)
{
string tmp = Parse(ms);
if (tmp != null)
{
txtAdoc.Text = tmp;
txtAdoc.Focus();
txtAdoc.SelectAll();
}
else
{
txtAdoc.Text = "Parse Failed";
}
}
else
{
txtAdoc.Text = "Clipboard Load failed";
}
}
void DumpHtmlClipboard()
{
MemoryStream ms = GetHtmlClipboard();
if (ms != null)
{
string tmp = GetHtmlText(ms);
if (tmp != null)
{
txtAdoc.Text = tmp;
//txtAdoc.Focus();
//txtAdoc.SelectAll();
}
else
{
txtAdoc.Text = "Parse Failed";
}
}
else
{
txtAdoc.Text = "Clipboard Load failed";
}
}
static MemoryStream GetHtmlClipboard()
{
return Clipboard.GetData("Html Format") as MemoryStream;
}
static string GetHtmlText(MemoryStream ms)
{
int startHtml = -1;
int endHtml = -1;
// ヘッダ情報(StartHTML, EndHTML)を取得
// StartHTML:nnnnnnnnnn
// EndHTML:nnnnnnnnnn
//public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen)
// leaveOpen=trueで開かないと、msが閉じてしまう。
using (var sr = new StreamReader(ms, Encoding.UTF8, true, 1024, true))
{
Regex rx = new Regex(@"^(StartHTML:|EndHTML:)([0-9]+)");
int lineCount = 0;
string s;
while ((s = sr.ReadLine()) != null)
{
lineCount++;
Match m = rx.Match(s);
if (m.Success)
{
int n = Convert.ToInt32(m.Groups[2].Value, 10); // 10進
if (m.Groups[1].Value == "StartHTML:")
{
startHtml = n;
}
else
{
endHtml = n;
}
if (startHtml >= 0 && endHtml > startHtml)
{
break;
}
}
if (lineCount >= ExpectedHeaderMaxLines)
{
break;
}
}
}
// HTML部分を取得(EndHTMLは無視)
ms.Position = startHtml;
using (var sr = new StreamReader(ms, Encoding.UTF8, false))
{
return sr.ReadToEnd();
}
}
// stypeタグの中身を返す
static string GetStyleText(string htmlText, out int endPos)
{
string retString = null;
endPos = 0;
int styleStartTagPos = 0;
int maxStyleTag = 50;
int styletagCounter = 0;
while (styletagCounter < maxStyleTag)
{
styletagCounter++;
styleStartTagPos = htmlText.IndexOf("<style>", styleStartTagPos);
if (styleStartTagPos < 0)
{
break;
}
styleStartTagPos += "<style>".Length;
int styleEndTagPos = htmlText.IndexOf("</style>", styleStartTagPos);
if (styleEndTagPos < 0)
{
break;
}
endPos = styleEndTagPos + "</style>".Length;
int commentStartTagPos = htmlText.IndexOf("<!--", styleStartTagPos);
if (commentStartTagPos >= 0)
{
commentStartTagPos += "<!--".Length;
}
int commentEndTagPos = (commentStartTagPos < 0) ? -1 : htmlText.IndexOf("-->", commentStartTagPos);
if (commentStartTagPos >= 0 && commentEndTagPos > commentStartTagPos && commentEndTagPos < styleEndTagPos)
{
// コメントタグがある場合、コメントタグを除去(コメントタグ内のみを返す)
retString += htmlText.Substring(commentStartTagPos, commentEndTagPos - commentStartTagPos);
}
else
{
// コメントタグがない場合
retString += htmlText.Substring(styleStartTagPos, styleEndTagPos - styleStartTagPos);
}
styleStartTagPos = endPos;
}
return retString;
}
static int IndexOfUsingRegex(string src, int startPos, Regex rTarget, out int length)
{
Match m = rTarget.Match(src, startPos);
if (!m.Success)
{
length = 0;
return -1;
}
length = m.Groups[0].Length;
return m.Groups[0].Index;
}
// tableタグ込みで返す
// ネストは許容しない(検出してnullを返す)
static string GetFirstTableText(string htmlText, int pos)
{
int len;
int tableStartTagPos = IndexOfUsingRegex(htmlText, pos, rxTableBeginTag, out len);
if (tableStartTagPos < 0)
{
return null;
}
int tableEndTagPos = htmlText.IndexOf("</table>", tableStartTagPos + len);
if (tableEndTagPos < 0)
{
return null;
}
int dummy;
int tmpPos = IndexOfUsingRegex(htmlText, tableStartTagPos + len, rxTableBeginTag, out dummy);
if (tmpPos >= 0 && tmpPos < tableEndTagPos)
{
// ネストしている(閉じタグよりも手前の位置に2つ目の開始タグを検出した)
return null;
}
tableEndTagPos += "</table>".Length;
return htmlText.Substring(tableStartTagPos, tableEndTagPos - tableStartTagPos);
}
//static readonly Regex rxCss = new Regex(@":;", RegexOptions.Multiline | RegexOptions.IgnoreCase);
//static Dictionary<string,Dictionary<string,string>> ParseCssPart(string styleText)
//{
//}
// https://momdo.github.io/html/syntax.html#attributes-2
// 属性名は、制御文字、U+0020 SPACE、U+0022(")、U+0027(')、U+003E(>)、U+002F(/)、U+003D(=)、および非文字以外の1つ以上の文字で構成されなければならない。HTML構文において、外来要素に対するものでさえ、属性名は、ASCII小文字およびASCII大文字の任意の組み合わせで書かれてもよい。
// 属性値は、テキストが曖昧なアンパサンドを含めることができない追加の制限をもつ場合を除き、テキストおよび文字参照の混合物である。
// 引用符で囲まれない属性値構文
// ASCII空白文字 U+0022 QUOTATION MARK文字(")、
// U+0027 APOSTROPHE文字(')、U+003D EQUALS SIGN文字(=)、
// U+003C LESS-THAN SIGN文字(<)、U+003E GREATER-THAN SIGN文字(>)、
// またはU+0060 GRAVE ACCENT文字(`)文字を含んではならず、かつ空文字列であってはならない。
// 1 = 2 3 4
// <-------------------------------------> <--------------------------------> <-----> <------->
// <---------------------------------------------------------------->
static readonly Regex rxAttr = new Regex(@"\b([^\x00-\x1F\x20\x22\x27\x2F\x3D\x3E]+)\s*(?:=\s*(?:([^\x20\x22\x27\x3C\x3D\x3E\x60]+)|'([^']*)'|\x22([^x22]*)\x22))?", RegexOptions.Multiline | RegexOptions.IgnoreCase);
static Dictionary<string, string> ParseAttrs(string attrsStr)
{
var dict = new Dictionary<string, string>();
Match mAttr = rxAttr.Match(attrsStr);
while (mAttr.Success)
{
string key = mAttr.Groups[1].Value.ToLower();
string value = "";
if (mAttr.Groups[2].Length > 0)
{
value = mAttr.Groups[2].Value;
}
else if (mAttr.Groups[3].Length > 0)
{
value = mAttr.Groups[3].Value;
}
else if (mAttr.Groups[4].Length > 0)
{
value = mAttr.Groups[4].Value;
}
else
{ // without "="
// do nothing
}
if (!dict.ContainsKey(key))
{
dict.Add(key, value);
}
mAttr = mAttr.NextMatch();
}
return dict;
}
static string EscapeContentForAdocTableCell(string s)
{
// Replace (string input, string replacement);
s = rxTag.Replace(s, ""); // HTML全般のタグを消去
s = s.Replace("\r\n", " ")
.Replace("\n", " ")
.Replace("\r", " ")
.Replace("\t", " ")
.Replace("&nbsp;", " ")
.Replace("&lt;", "<")
.Replace("&gt;", ">")
.Replace("&amp;", "&")
.Replace("|", "{VBar}"); // ADoc用
return s;
}
static string ParseTableToAdoc(string tableText, Dictionary<string, Dictionary<string, string>> classFormat)
{
var sb = new StringBuilder();
Match m = rxTag.Match(tableText);
string lastStartTag = null;
int lastPos = -1;
int lastTdPos = -1;
int currentTdCount = 0;
int maxTdCount = 0;
sb.AppendLine("|===");
while (m.Success)
{
if (m.Groups[1].Length > 0)
{
string tag = m.Groups[1].Value;
string attrsStr = m.Groups[2].Value;
lastPos = m.Groups[0].Index + m.Groups[0].Length;
if (tag == "tr")
{
maxTdCount = Math.Max(maxTdCount, currentTdCount);
currentTdCount = 0;
}
else if (tag == "td")
{
lastTdPos = lastPos;
if (lastStartTag != "tr")
{
sb.Append(" ");
}
var attrs = ParseAttrs(attrsStr);
if (attrs.ContainsKey("colspan") || attrs.ContainsKey("rowspan"))
{
if (attrs.ContainsKey("colspan"))
{
sb.Append(attrs["colspan"]);
currentTdCount = currentTdCount + int.Parse(attrs["colspan"])-1;
}
if (attrs.ContainsKey("rowspan"))
{
sb.Append(".");
sb.Append(attrs["rowspan"]);
}
sb.Append("+");
}
if (attrs.ContainsKey("class"))
{
var format = classFormat["default"];
string classid = attrs["class"];
if (classFormat.ContainsKey(classid)){
format = classFormat[classid];
}
sb.Append(format["text-align"].Replace("general", "<").Replace("left", "<").Replace("center", "^").Replace("right", ">"));
sb.Append(".");
sb.Append(format["vertical-align"].Replace("general", "<").Replace("top", "<").Replace("middle", "^").Replace("bottom", ">"));
}
else
{
var format = classFormat["default"];
sb.Append(format["text-align"].Replace("general", "<").Replace("left", "<").Replace("center", "^").Replace("right", ">"));
sb.Append(".");
sb.Append(format["vertical-align"].Replace("general", "<").Replace("top", "<").Replace("middle", "^").Replace("bottom", ">"));
}
sb.Append("|");
currentTdCount++;
}
lastStartTag = tag;
}
else if (m.Groups[3].Length > 0)
{
string tag = m.Groups[3].Value;
int tagStartPos = m.Groups[0].Index;
//Console.WriteLine("</" + m.Groups[3].Value +">");
if (tag == "tr")
{
sb.AppendLine("");
}
else if (tag == "td")
{
string s = tableText.Substring(lastTdPos, tagStartPos - lastTdPos);
sb.Append(EscapeContentForAdocTableCell(s));
lastTdPos = -1;
}
lastPos = -1;
lastStartTag = null;
}
m = m.NextMatch();
}
sb.AppendLine("|===");
//整形
sb = sb.Replace("<.<", "");
string firstLine = "[cols=\"<.<a";
for (int i = 1; i < maxTdCount; i++)
{
firstLine += ",<.<a";
}
firstLine += "\",options=\"autowidth\"]";
sb.Insert(0, firstLine + Environment.NewLine);
return sb.ToString();
}
static string Parse(MemoryStream ms)
{
// debug code {
//string htmlText = File.ReadAllText("testdata_html_excel.txt");
// } end of debug code
string htmlText = GetHtmlText(ms);
int pos;
string styleText = GetStyleText(htmlText, out pos) ?? "";
Dictionary<string, Dictionary<string, string>> classFormat = GetFormat(styleText);
string tableText = GetFirstTableText(htmlText, pos);
return ParseTableToAdoc(tableText, classFormat);
}
static Dictionary<string, Dictionary<string, string>> GetFormat(string styleText)
{
int maxFormatNum = 100;
int counter = 0;
int endPos = 0;
Regex reg = new Regex(@"[\t {};]");
// デフォルト値のデフォルト値
var dctDefault = new Dictionary<string, string>();
dctDefault.Add("color", "black");
dctDefault.Add("background", "black");
dctDefault.Add("text-align", "left");
dctDefault.Add("vertical-align", "top");
// デフォルト値取得
int startTdTagPos = styleText.IndexOf("td\r\n\t{", 0);
int endTdTagPos = styleText.IndexOf(";}", startTdTagPos);
string defauletFromatText= styleText.Substring(startTdTagPos, endTdTagPos + ";}".Length-startTdTagPos);
var defaultLines = reg.Replace(defauletFromatText, "").Replace("\r\n", "\n").Split(new[] { '\n', '\r' });
foreach (string line in defaultLines)
{
string[] words = line.Split(':');
if (dctDefault.ContainsKey(words[0]))
{
dctDefault[words[0]] = words[1];
}
}
var ret = new Dictionary<string, Dictionary<string, string>>();
ret.Add("default", dctDefault);
// 各クラスの書式を取得
while (counter < maxFormatNum)
{
counter++;
int formatStartTagPos = styleText.IndexOf(".xl", endPos);
if (formatStartTagPos < 0)
{
break;
}
formatStartTagPos += ".xl".Length;
int formatEndTagPos = styleText.IndexOf(";}", formatStartTagPos);
if (formatEndTagPos < 0)
{
break;
}
endPos = formatEndTagPos + ";}".Length;
string formatText = styleText.Substring(formatStartTagPos, endPos - formatStartTagPos);
var lines = reg.Replace(formatText, "").Replace("\r\n", "\n").Split(new[] { '\n', '\r' });
string classid = "xl" + lines[0];
var dctFormat = new Dictionary<string, string>();
dctFormat.Add("color", dctDefault["color"]);
dctFormat.Add("background", dctDefault["background"]);
dctFormat.Add("text-align", dctDefault["text-align"]);
dctFormat.Add("vertical-align", dctDefault["vertical-align"]);
foreach (string line in lines)
{
string[] words = line.Split(':');
if (dctFormat.ContainsKey(words[0]))
{
dctFormat[words[0]] = words[1];
}
}
ret.Add(classid, dctFormat);
}
return ret;
}
[STAThread]
static void Main(string[] args)
{
Application.Run(new SampleForm());
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// SampleForm
//
this.ClientSize = new System.Drawing.Size(284, 261);
this.Name = "SampleForm";
this.Load += new System.EventHandler(this.SampleForm_Load);
this.ResumeLayout(false);
}
private void SampleForm_Load(object sender, EventArgs e)
{
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
// アセンブリに関連付けられている情報を変更するには、
// これらの属性値を変更してください。
[assembly: AssemblyTitle("EcxelToAdocConverter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EcxelToAdocConverter")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから
// 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、
// その型の ComVisible 属性を true に設定してください。
[assembly: ComVisible(false)]
// このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります
[assembly: Guid("36aa7526-71ef-4009-b21e-55a0ff4cfa12")]
// アセンブリのバージョン情報は次の 4 つの値で構成されています:
//
// メジャー バージョン
// マイナー バージョン
// ビルド番号
// Revision
//
// すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます
// 既定値にすることができます:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment