相关文章推荐
聪明伶俐的甘蔗  ·  让音乐架起中美友好的桥梁_中华人民共和国驻纽 ...·  1 年前    · 
豁达的红烧肉  ·  将SQLServer中的负数varchar和 ...·  2 年前    · 
好帅的海龟  ·  这一次,89岁谷建芬老师忍无可忍,她坚决发表 ...·  3 年前    · 
兴奋的铅笔  ·  电动微型车5月销量暴跌40%,让人不禁想问: ...·  3 年前    · 
乐观的西红柿  ·  我被地球绑架了漫画|官方在线漫画全集-快看漫画·  3 年前    · 
Code  ›  Word自动化(C# + Python)(持续更新中...)开发者社区
python c# docx
https://cloud.tencent.com/developer/article/1525989
有腹肌的煎饼果子
3 年前
作者头像
sean_yang
0 篇文章

Word自动化(C# + Python)(持续更新中...)

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > Sorrower的专栏 > Word自动化(C# + Python)(持续更新中...)

Word自动化(C# + Python)(持续更新中...)

作者头像
sean_yang
发布 于 2019-10-23 18:47:12
1.3K 0
发布 于 2019-10-23 18:47:12
举报

前言

Word就是那种很难用, 很丑陋, 但是你不得不用的东西, 在这一点上, 它甚至比Windows更甚。 Windows可以用macOS + PlayStation进行1000%的替代。 但是Office不能够, 并不是没有比Office更好的东西, 这是一个历史残留问题, 就像牙膏厂CPU里面, 那些莫名其妙的字段一样。 总之, 这里通过使用一些库, Python的python-docx, C#的pdfbox和npoi, 来让对Word和PDF的处理变得更加自动化一些。 最后, 如果你想设计一些定制化的功能, 还是希望可以从官方文档进行学习。

读取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

而且, 官方文档 写得很不错, 可用于学习。

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)
 
推荐文章
聪明伶俐的甘蔗  ·  让音乐架起中美友好的桥梁_中华人民共和国驻纽约总领事馆
1 年前
豁达的红烧肉  ·  将SQLServer中的负数varchar和null值转换为decimal -火山引擎
2 年前
好帅的海龟  ·  这一次,89岁谷建芬老师忍无可忍,她坚决发表律师声明|那英|刀郎|歌曲|刘欢|杨坤|新歌|毛阿敏_网易订阅
3 年前
兴奋的铅笔  ·  电动微型车5月销量暴跌40%,让人不禁想问:为何买的人越来越少?|小型车|奇瑞汽车|吉利熊猫|五菱宏光|宝骏汽车_网易订阅
3 年前
乐观的西红柿  ·  我被地球绑架了漫画|官方在线漫画全集-快看漫画
3 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号