Word自动化(C# + Python)(持续更新中...)
目录
- 前言
- 读取Word内容
- NPOI
- NPOI安装
- NPOI提取Word内容
- 用Costura.Fody打包DLL
- python-docx
- 读取PDF内容
- python-docx自动生成Word
- 全局字体
- 内容字体
- 单元格合并
- 最后
前言
Word就是那种很难用, 很丑陋, 但是你不得不用的东西, 在这一点上, 它甚至比Windows更甚(毕竟Gates是通过帮水果写Office才有机会接触Macintash和施乐的嘛, 你听过的, 两个小偷的故事). Windows可以用macOS + PlayStation进行1000%的替代, 没有多打0(手动滑稽). 但是Office不能够, 并不是没有比Office更好的东西, 这是一个历史残留问题, 就像牙膏厂CPU里面, 那些莫名其妙的字段一样.
总之, 这里通过使用一些库, Python的python-docx, C#的pdfbox和npoi, 来让对Word和PDF的处理变得更加自动化一些.
最后, 如果你想设计一些定制化的功能, 还是希望可以从官方文档进行学习, 而不是通过看博客. 尤其是当你只能够用某度, 而不是某歌, 那些前几页给出的搜索结果老旧又不顶用, 说真的, 用某度还不如在博客网站进行站内搜索, 不过我最近发现某日头条的全网搜索给出的结果还不错, 如果你不能某歌, 可以用下某日头条, 再不济用某应(Bing)也好过某度.
读取Word内容
好了, 不多说废话了. 直接看从Word获取内容. 这里可以用C#的NPOI和python-docx实现.
NPOI
NPOI安装
来看下维基的介绍. Apache POI是Apache软件基金会的开放源码库, POI提供API给Java程序对Microsoft Office格式文件读和写的功能. .NET的开发人员则可以利用NPOI(POI for .NET)来访问POI的功能.
其实, 最近这几年, 巨硬通过推出像.NET Core这样的跨平台应用程序开发框架, 已经让C#有了一点起死回生的迹象, 我不喜欢巨硬, 但我很推崇这种战略, 当然了, 甚至在硬件上推出了Duo这样的Surface安卓设备. 虽然之前写Unity游戏的时候用过一些C#, 但是这次是我第一次从软件开发的角度使用C#, 不得不说, NuGet令我印象深刻, 很好用.
这里假设你已经装了vs2019或者旧一点的版本, 但是注意, .NET Framework的程序依旧只能在Windows进行开发, 因为我暂时还没有摸像Mono这样的环境, 如果你感兴趣, 可以试下.
- 新建.NET Framework控制台应用:
- 然后你只需要在搜索框输入nuget, 点击管理NuGet程序包:
- 之后搜索NPOI, 点击安装, 就可以了. 可能比起mac的
brew install
, linux的apt-get install
和python的pip3 install
多了两步, 但是我已经很满意了, 比什么找DLL, 拷贝DLL之类的, 要显得9102的多.
- 安装之后, 在右侧的解决方案引用里面, 已经可以看到添加的库了:
NPOI提取Word内容
其实NPOI非常强大, 足以用来做和Word有关的一切了, 但是, 这里只演示一下提取Word中的内容, 因为后面有python-docx这样更加轻巧的库, 不需要vs不需要Windows, 你就可以处理docx类型的文件了.
源码如下:
using NPOI.XWPF.UserModel; using System.IO; using System.Text; namespace getWord { class Program { static void Main(string[] args) { string in_path = System.Console.ReadLine(); string out_path = System.Console.ReadLine(); Stream stream = File.OpenRead(in_path); XWPFDocument doc = new XWPFDocument(stream); string text = ""; string tmp_text; foreach (var para in doc.Paragraphs) { tmp_text = para.ParagraphText; if (tmp_text.Trim() != "") text += tmp_text + "\n"; } StreamWriter swPdfChange = new StreamWriter(out_path, false, Encoding.GetEncoding("gb2312")); swPdfChange.Write(text); swPdfChange.Close(); } } }
我从控制台读取了输入输出路径, 然后循环读取Word内容写入缓存, 最后转码成gb2312到输出文件.
最终, 我还是希望你去NPOI官网看看.
用Costura.Fody打包DLL
如果你就这样直接生成Release版本, 你会被老板骂的狗血淋头, 太不专业了. 至少你应该把DLL打包进EXE或DLL.
你可以把DLL作为资源文件进行打包, 但是这样不优雅, 很土. 同样, 我们用9102年应该用的方法.
在NuGet搜索Costura.Fody, 安装即可. 这样的话, 编译成Release版本的时候, 直接就打包成一个EXE文件了.
python-docx
好了, 到了Python, 一切都舒服了, 忘记刚才为了写C#安装的好几个G甚至几十个G的vs吧, 毕竟Gates说过'640K is more memory than anyone will ever need.'(手动滑稽)
现在你只需要:
pip3 install python-docx
而且, 官方文档写得很不错, 并且我发现在作业部落(对, 就是我的macOS上有什么里面推荐的那个cmd markdown)的一篇python-docx中文, 几乎就是官方中文. 所以, 我基本就靠这两个外加谷歌, 完成了全部的内容学习, 当然, 你会发现, 难点还是在Table处理和样式修改那里.
import docx doc = docx.Document('./t.docx') doc_text = '' doc_table_text = '' for paragraph in doc.paragraphs: doc_text += paragraph.text + '\n' for table in doc.tables: for row in table.rows: for cell in row.cells: doc_table_text += cell.text + '\n' with open('./tt.txt', 'w') as f: f.write(doc_text) f.write(doc_table_text) # doc.save ('./tt.docx')
代码其实很好懂, 关于python-docx的一些细节操作, 除了官方文档, 我在后面的自动化生成Word里面也会分享一些我的处理经验, 当然, 更多的是处理时候的坑(手动无奈).
读取PDF内容
同样, 这次用的是C#的库, 名为Pdfbox. 其实呢, 这个Pdfbox是个Java库. 是由Apache PDFBox团队为.NET生成的.
using org.apache.pdfbox.pdmodel; using org.apache.pdfbox.util; using System.IO; using System.Text; namespace getPDFCon { class Program { static void Main(string[] args) { string in_path = System.Console.ReadLine(); string out_path = System.Console.ReadLine(); PDDocument doc = PDDocument.load(in_path); PDFTextStripper pdfStripper = new PDFTextStripper(); string text = pdfStripper.getText(doc); // Console.WriteLine(Utf8ToGB2312(text)); // Console.ReadKey(); StreamWriter swPdfChange = new StreamWriter(out_path, false, Encoding.GetEncoding("gb2312")); swPdfChange.Write(text); swPdfChange.Close(); } } }
和之前读取Word几乎是一样的思路, 不多说了.
python-docx自动生成Word
这里我来细说一下, python-docx的一些操作. 从样式修改, 表格合并处理这些难点来谈. 后续也会逐步更新新遇到的坑.
全局字体
首先, 你可以设置全局字体.
doc.styles['Normal'].font.name = u'宋体' doc.styles['Normal'].font.size = Pt (9) doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
注意, 如果是汉字, 第三行是必须要加的, 否则不生效. 第二行是设置字体大小, 你需要用
from docx.shared import Pt
进行导包. 当然, 你直接导入整个docx包就完事了.
内容字体
如果你想只修改某段内容的字体, 不影响全局, 之前的方案就不行.
p = doc.add_paragraph () font = p.add_run ('标题').font font.bold = True font.size = Pt (14) p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
这里看到一个p.add_run, 这是给当前Paragraph实例添加的Run实例, 也就是运行时候的一些设置, 只对当前Paragraph实例生效. 来看下和直接设置Paragraph实例属性的比较.
doc = Document () p = doc.add_paragraph () font = p.add_run ('标题1').font font.bold = True font.size = Pt (14) p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER p2 = doc.add_paragraph () p2.text = ('标题2') p2.style.font.size = Pt (20) p3 = doc.add_paragraph () p3.text = ('标题3') p3.style.font.size = Pt (40) doc.save ('a.docx')
这段代码在想象中应该是段落内容越来越大, 对吧, 但是很遗憾, 对于标题3的字体设置会覆盖标题2的字体设置, 但是通过run对象进行设置的标题1就不会受到影响, 来看图说话:
这样一来, 想要很好处理某段内容的风格, 就必须使用run. 否则就会关联其他. 修改下代码, 都设置成add_run, 看看是否如此:
很好, 这才是想要的效果. 同理, 在表格内容里面也是如此, 不多赘述.
但是还有一点要注意, 比如你已经通过, p.text进行文字赋值, 但是, 你又用, p.add_run ('标题').font进行设置, 那么你会得到两份内容. 所以, 这里要特别注意, 如果通过样式填充, 就不用再用text字段进行赋值.
单元格合并
比如我现在建立一张表, 尝试合并. 然后你会发现, 合并之后, 把两份内容都保留了, 如果这是你需要的, 自然没有问题. 但是如果不是, 你就要思考内容合并的策略, 你不可能一个一个设置. 一个比较合理的策略就是用临时变量保留你要的内容, 合并完成之后, 将临时变量内容覆盖合并后的内容.
最后
其实, 不论是NPOI还是python-docx, 已经是非常不错的库了, 都可以很好地帮助开发者进行自动化word的生成. 如果你不这么觉得, 我举个反例. Microsoft.Office.Interop.Word是巨硬提供的com组件, 那么要如何使用它呢, 你要先装Windows, 再装Office, Office2013对应这个com组件的15.x版本, Office2007对应组件的12.x. 然后你写完代码, 每次运行还需要启动Word, 可以后台启动, 但终归是启动了, 所以效率非常低.
当然, 本章内容还会在后续使用当中持续更新, 直到我觉得没有必要更新了. 喜欢可以点个赞, 有意见或者建议, 评论区见哦~
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
除了语法简单,Python的简洁还体现在哪?
《Java编程思想 (Thinking in Java)》 的作者Bruce Eckel给予了Python高度评价,他说:Life is short, you need Python。很多人初识Python,是因为这句话。 成功的背后,是一个坚定的选择 生命如此美好,但是太过短暂。要想在有限时间内,最高效的做出成绩,选择比努力要更重要。如何选择一门编程语言,是个争论不休的永久话题。但是,有一个问题的答案是明确的,使用人数和增长率,是衡量是否成功的重要标准。吉多·范罗苏姆是Python的设计者和创造者,他的这一产品能得到全世界那么多程序员的喜爱和选择,是因为作对了什么呢? 失败是成功之母 吉多在创造Python之前,参与设计了ABC这一种教学语言。ABC非常的优美和强大,但最终没有获得成功。吉多在总结失败原因的时候发现,ABC不够开放,普适性比较差,使用的人数得不到快速扩增,这样就不会产出足够的影响力,以致难以让更多的人加入进来。 表面是三点,其实只有一个源起点 有三点特征,成就了Python。第一,简洁性;第二,易读性;第三,可扩展性。因为简洁,所以更易学习。Python没有花哨的语法...
- 下一篇
Spring Boot 多数据源,整合 Atomikos 实现分布式事务
前言 由于最近的项目需要整合两个数据库,有些业务逻辑也涉及到两个数据库同时插入、更新的操作;所以就涉及到跨数据库的数据一致性问题。于是基于 Spring Boot 整合了 Atomikos 的一个项目 demo。项目源码地址:https://github.com/WongMinHo/spring-boot-api-starter 介绍 分布式事务: 分布式事务,可以理解为:由于分布式而引起的事务不一致的问题。随着项目做大,模块拆分,数据库拆分。一次包含增删改操作数据库涉及到了更新两个不同物理节点的数据库,这样的数据库事务只能保证自己处理的部分的事务,但是整个的事务就不能保证一致性。 JTA: JTA(java Transaction API)是 JavaEE 13 个开发规范之一,java 事务API,允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JDBC 驱动程序的 JTA 支持极大地增强了数据访问能力。事务就是保证数据的有效性,数据的一致性。 Atomikos: Atomikos 是一个为 Java 平台提供增值服务的并且开源类事务管理器,主要用于...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Hadoop3单机部署,实现最简伪集群
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题