You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
require'nokogiri'require'zip'zip=Zip::File.open('/Users/rcc0016748/Desktop/hello.docx')document=zip.glob('word/document*.xml').first# 可以拿到原始的 xml 结构document_xml=document.get_input_stream.read# 生成 xml 实例对象doc=Nokogiri::XML(document_xml)
基于 zip 跟 nokogiri 这2个包。
通过 Nokogiri 生成的 xml 文档实例后,就可以对数据进行读取。
原来,docx 文件是基于 xml 格式来保存数据的啊!
1、背景
一开始的需求,是要支持写入的文字能够带样式。
那首先,得知道基本的结构吧?
有点懵……
文档说明貌似没怎么找得到,直接从代码下手吧~
2、处理
先创建一个最简单的
docx
文件。先简单过一下
docx
项目的整体结构。从document.rb
文件入手,来看看是什么样的数据结构。在
irb
中进行读取:基于
zip
跟nokogiri
这2个包。通过
Nokogiri
生成的xml
文档实例后,就可以对数据进行读取。原来,
docx
文件是基于xml
格式来保存数据的啊!至于生成的
xml
实例可以怎么用?比如,段落的匹配:
比如,书签的匹配:
匹配的数据就跟使用使用html选择器拿到的数据差不多,符合条件就会被收集在数组里。
另外,在终端查看生成的
xml
为:抛去前后一些整体页面的结构,来看看第一个段落:
一些标签大概的意思可以参考:word xml 各个标签含义 - JavaShuo
主要意思就是:在一个
<w:r>(也叫textrun)
中,可以包含:<w:rPr>
包起来的各种各种属性,<w:t>
真正的文本内容再来看看这段:
<w:rPr>
的属性值:<w:color>
表示颜色属性,w:val
用来设置具体的颜色。<w:u>
表示下划线属性,w:val="single"
用来设置具体的下划线类型。好了。背景就是这样子。
那看回我们的需求,希望能够支持写入样式。那么对应的做法就是:
多加一个参数,用来接收想要的样式,然后给对应的节点
<w:r>
增加它<w:rPr>
中的各个属性:颜色、加粗、下划线、字体大小等等。在
docx
中,插入文字的主要方法有:docx gem
中,经过nokogiri
解析xml
后,<w:r>
对应的类是lib/docx/containers/text_run.rb
。<w:r>
xml 节点存于@node
中:初始化:
原先设置文本内容的方法,
text=
:所以,目前只能插入文字,并没有样式。
现在来看看怎么支持?
我们可以添加一个方法:在
text=(content)
的基础上,再额外追加样式。formatting
的参数支持:剩下的重任就是
apply_formatting
身上了!!!!!再来看看这个例子,
<w:r>
xml 节点存于@node
中:大概思路为:
@node
中,搜索一下有没有<w:rPr>
,没有的话,需要创建。formatting
,在<w:rPr>
中追加具体的属性。那现在来看看
apply_formatting
:3、思路总结
xml
结构进行存储。zip
进行文件读取, 用nokogiri
进行xml
的解析,生成对应的节点。text_run
),用<w:r>
包起来,里面包含<w:rPr>
属性节点 +<w:t>
内容节点。<w:rPr>
下的具体属性(斜体、加粗、下划线等)通过此次改动,学习到了 docx 文档存储方式与相关处理。
4、其他
这个需求,是尽量让业务方减少改动,尽量扩展。
假如扩展不了的话,也可以通话其他方案去实现,比如单独使用相关的服务,通过接口调用的方式不再基于
docx
做操作等等。此次调整参考一个好几年前未合的merge request: https://github.com/ruby-docx/docx/pull/26,做了相关的改动。
5、文章
The text was updated successfully, but these errors were encountered: