Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
ADoc
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
QCD
ADoc
Commits
8dec7eaa
Commit
8dec7eaa
authored
Mar 25, 2021
by
oshima
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Excel⇒Adoc変換ツール
parent
b57adfcb
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
842 additions
and
0 deletions
+842
-0
EcxelToAdocConverter.exe
Tool/ExcelToAdocConverter/EcxelToAdocConverter.exe
+0
-0
readme.txt
Tool/ExcelToAdocConverter/readme.txt
+20
-0
EcxelToAdocConverter.sln
Tool/ExcelToAdocConverter/source/EcxelToAdocConverter.sln
+31
-0
App.config
...celToAdocConverter/source/EcxelToAdocConverter/App.config
+6
-0
EcxelToAdocConverter.csproj
...r/source/EcxelToAdocConverter/EcxelToAdocConverter.csproj
+82
-0
ExcelToAdocConverter.cs
...erter/source/EcxelToAdocConverter/ExcelToAdocConverter.cs
+547
-0
ExcelToAdocConverter.resx
...ter/source/EcxelToAdocConverter/ExcelToAdocConverter.resx
+120
-0
AssemblyInfo.cs
...er/source/EcxelToAdocConverter/Properties/AssemblyInfo.cs
+36
-0
No files found.
Tool/ExcelToAdocConverter/EcxelToAdocConverter.exe
0 → 100644
View file @
8dec7eaa
File added
Tool/ExcelToAdocConverter/readme.txt
0 → 100644
View file @
8dec7eaa
■使い方
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 大島追記
・水平垂直の揃えに対応しました。
・デフォルト値を以下のようにしました。
・列の幅は自動調整
Tool/ExcelToAdocConverter/source/EcxelToAdocConverter.sln
0 → 100644
View file @
8dec7eaa
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
Tool/ExcelToAdocConverter/source/EcxelToAdocConverter/App.config
0 → 100644
View file @
8dec7eaa
<?
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
Tool/ExcelToAdocConverter/source/EcxelToAdocConverter/EcxelToAdocConverter.csproj
0 → 100644
View file @
8dec7eaa
<?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
Tool/ExcelToAdocConverter/source/EcxelToAdocConverter/ExcelToAdocConverter.cs
0 → 100644
View file @
8dec7eaa
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
(
" "
,
" "
)
.
Replace
(
"<"
,
"<"
)
.
Replace
(
">"
,
">"
)
.
Replace
(
"&"
,
"&"
)
.
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
Tool/ExcelToAdocConverter/source/EcxelToAdocConverter/ExcelToAdocConverter.resx
0 → 100644
View file @
8dec7eaa
<?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
Tool/ExcelToAdocConverter/source/EcxelToAdocConverter/Properties/AssemblyInfo.cs
0 → 100644
View file @
8dec7eaa
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"
)]
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment