markdown文件转自定义风格docx
前言
一个学长给安排的小任务,实现markdown文件转化为公司风格的docx文件
我们组使用flexmarkjava(较为复杂但稳定),另一组使用pandoc(快速实用,但表格转换上会出现问题)
使用flexmark的原因为它项目工程中的子项目能实现m2d功能,但转换出的效果为作者定义的模板风格,要达到任务目标还需对其加工修改才能使用。
碎碎念:T^T 在实现这个过程中深感自己在编程过程中太菜了,不会maven,从eclipse跳到idea 导入个工程还各种bug需要学长帮忙弄 T^T ; 初次使用git 注册了自己的github账号 T^T ~ 头一次看一个对我而言很大很大很大的一个项目(flexmark) 学会了一丢丢如何快速判断这个项目是否可以使用有价值(一看Readme而看时间和活跃,一般能从ReadMe中找到自己想了解的东西)。
docx文档解析
解析工具
OPEN XML SDK
如图为该工具打开某docx文件的相关界面
xml代码的C#实现
Documentation:
该工具有助于理解WML包(docx文件实际为为WordprocessingML 包)中xml文件结构及内容含义~极具参考价值,并能自动生成相关C#代码。
WML包结构
官方文档
这里详细介绍后期需要修改的两个文件,word目录下的style.xml和number.xml
其他xml文件含义参考官网文档。
style.xml
以公司docx文档为例 ,style.xml定义了文档的风格样式,如标题、表格、正文段落、题注、注脚、编号风格等。
具体反映在docx文档中的样式:
映射关系举例:Table Heading 表头样式 注意~这里的styleId值,一会在实现文档转换的时候会提到
style.xml部分内容:
<w:style w:type="paragraph" w:styleId="TableHeading">
<w:name w:val="Table Heading"/>
<w:basedOn w:val="TableContents"/>
<w:qFormat/>
<w:pPr>
<w:suppressLineNumbers/>
<w:shd w:val="clear" w:fill="DDDDDD"/>
<w:bidi w:val="false"/>
<w:jc w:val="center"/>
</w:pPr>
<w:rPr>
<w:b/>
<w:bCs w:val="false"/>
</w:rPr>
</w:style>
在docx中具体表现
这很好理解,其属性与xml文件中定义的一一对应,可类比其他属性。
注:样式有些部分可以隐藏,在管理样式中可以查看所有样式。xml文件中隐藏: <w:semiHidden/>
number.xml
该文件定义了编号的格式:
<w:abstractNum w:abstractNumId="1">
<w:lvl w:ilvl="0">
<w:start w:val="1"/>
<w:numFmt w:val="none"/>
<w:pStyle w:val="Heading1"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:hanging="0" w:left="0"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="1">
<w:start w:val="1"/>
<w:numFmt w:val="none"/>
<w:pStyle w:val="Heading2"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:hanging="0" w:left="0"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="2">
<w:start w:val="1"/>
<w:numFmt w:val="none"/>
<w:pStyle w:val="Heading3"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:hanging="0" w:left="0"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="3">
<w:start w:val="1"/>
<w:numFmt w:val="none"/>
<w:pStyle w:val="Heading4"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:hanging="0" w:left="0"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="4">
<w:start w:val="1"/>
<w:numFmt w:val="none"/>
<w:pStyle w:val="Heading5"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:hanging="0" w:left="0"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="5">
<w:start w:val="1"/>
<w:numFmt w:val="none"/>
<w:pStyle w:val="Heading6"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:hanging="0" w:left="0"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="6">
<w:start w:val="1"/>
<w:numFmt w:val="none"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:hanging="0" w:left="0"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="7">
<w:start w:val="1"/>
<w:numFmt w:val="none"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:hanging="0" w:left="0"/>
</w:pPr>
</w:lvl>
<w:lvl w:ilvl="8">
<w:start w:val="1"/>
<w:numFmt w:val="none"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:hanging="0" w:left="0"/>
</w:pPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="2">
<w:lvl w:ilvl="0">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val="•"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:tabs>
<w:tab w:pos="227" w:val="num"/>
</w:tabs>
<w:ind w:hanging="227" w:left="227"/>
</w:pPr>
<w:rPr>
<w:rFonts w:cs="OpenSymbol"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="1">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val="•"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:tabs>
<w:tab w:pos="454" w:val="num"/>
</w:tabs>
<w:ind w:hanging="227" w:left="454"/>
</w:pPr>
<w:rPr>
<w:rFonts w:cs="OpenSymbol"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="2">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val="•"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:tabs>
<w:tab w:pos="680" w:val="num"/>
</w:tabs>
<w:ind w:hanging="227" w:left="680"/>
</w:pPr>
<w:rPr>
<w:rFonts w:cs="OpenSymbol"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="3">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val="•"/>
<w:lvlJc w:val="left&#