Skip to content

Commit b82bf32

Browse files
authored
Create RenZhengFei-PDF-Code.md
1 parent 404dc6f commit b82bf32

File tree

1 file changed

+237
-0
lines changed

1 file changed

+237
-0
lines changed

RenZhengFei-PDF-Code.md

+237
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
2+
### **0、程序思路**
3+
4+
要实现把 md 格式的文件转换成 pdf,需要用到以下两个库。
5+
6+
7+
8+
1. markdown
9+
2. wkhtmltopdf
10+
11+
12+
13+
直接把 md 转换成 pdf 的效果是非常不好的,所以我们可以先把 md 文件转换成 html 文件,然后在把 html 文件转换成 pdf。这样整体的效果就非常的好。
14+
15+
16+
17+
而上方的两个库就对应着把 md 转成 html,把 html 转成 pdf。所以我们首先要把这两个库进行安装。
18+
19+
20+
21+
### **1、md2html**
22+
23+
为了将 md 格式转换成 html 文件,我们需要用到 markdown 和 codecs 这两个库。
24+
25+
**1.1 Python-Markdown**
26+
27+
Python-Markdown 是 John Gruber 的 Markdown 的 Python 实现。利用这个库我们就可以很容易把 md 格式的文件转换成 html 文件。
28+
29+
安装方式「**pip install markdown**
30+
31+
随后我们使用 markdown.markdown() 函数就可以读取 md 文件里的内容了。
32+
33+
34+
35+
**1.2 codecs**
36+
37+
在 md2html 函数中还用到了 codecs 这个库,这个库是用来保证文件读取的过程中,不出现编码的问题。你也可以把它理解成 open 函数,用来读取创建文件用的。
38+
39+
40+
41+
**1.3 完整代码**
42+
43+
```python
44+
import markdown
45+
import os
46+
import codecs
47+
48+
head = """<!DOCTYPE html>
49+
<html>
50+
<head>
51+
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
52+
<style type="text/css">
53+
code {
54+
color: inherit;
55+
background-color: rgba(0, 0, 0, 0.05);
56+
}
57+
</style>
58+
</head>
59+
<body>
60+
"""
61+
62+
foot = """
63+
</body>
64+
</html>
65+
"""
66+
filepath = "E:/RZF/RenZhengfei-masterALL"
67+
savepath = "E:/RZF/RenZhengfei-masterALL-html"
68+
if not os.path.isdir(savepath):
69+
os.mkdir(savepath)
70+
os.chdir(savepath)
71+
72+
i = 0
73+
pathDir = os.listdir(filepath)
74+
for allDir in pathDir:
75+
if (allDir == "pdf"):
76+
continue
77+
name = allDir
78+
print(name)
79+
80+
os.chdir(filepath)
81+
fp1 = codecs.open(name, mode="r", encoding="utf-8")
82+
text = fp1.read()
83+
html = markdown.markdown(text)
84+
fp1.close()
85+
#print(html)
86+
87+
fname = name.replace('md', 'html')
88+
89+
#f2 = '%s.html' % (fname)
90+
os.chdir(savepath)
91+
fp2 = codecs.open(fname, "w", encoding="utf-8", errors="xmlcharrefreplace")
92+
fp2.write(head + html + foot)
93+
fp2.close()
94+
95+
print(i)
96+
```
97+
98+
99+
100+
**整个代码的逻辑:**
101+
102+
利用 markdown 读取 md 文件,然后在用 codeces 创建新的 html 文件。最后注意的是:在开头定义好 html 头部和尾部的 css 代码,中间的内容用读取到的 md 内容进行填充。
103+
104+
105+
106+
### **2、 html2pdf**
107+
108+
**2.1 wkhtmltopdf**
109+
110+
wkhtmltopdf 是一个开源、简单而有效的命令行 shell 程序,它可以将任何 HTML (网页)转换为 PDF 文档或图像(jpg、png 等)。
111+
112+
我们首先需要去官网去下载对应的程序到本地环境中。
113+
114+
https://wkhtmltopdf.org/downloads.html
115+
116+
而在 Python 中我们要通过 pdfkit 这个库来调用 wkhtmltopdf,所以我们还要安装下 pdfkit 库。
117+
118+
直接使用「**pip install pdfkit**」即可安装。
119+
120+
**2.2 完整代码**
121+
122+
```python
123+
import time
124+
import pdfkit
125+
import os
126+
127+
wk_path = 'E:/data/wkhtmltox/bin/wkhtmltopdf.exe'
128+
config = pdfkit.configuration(wkhtmltopdf=wk_path)
129+
130+
filepath = "E:/RZF/RenZhengfei-masterALL-html"
131+
savepath = "E:/RZF/RenZhengfei-masterALL-pdf"
132+
time1 = time.time()
133+
pathDir = os.listdir(filepath)
134+
for allDir in pathDir:
135+
if (allDir == "pdf"):
136+
continue
137+
name = allDir
138+
print(name)
139+
htmlpath=filepath+"\\"+name
140+
print(htmlpath)
141+
name = name.replace('html', 'pdf')
142+
os.chdir(savepath)
143+
pdfkit.from_url(htmlpath, name, configuration=config)
144+
145+
time2 = time.time()
146+
print(str(time2 - time1)+" s")
147+
```
148+
149+
150+
151+
### **3、合并多个pdf文件**
152+
153+
```python
154+
#!/usr/bin/env python3
155+
# -*- coding: utf-8 -*-
156+
'''
157+
本脚本用来合并pdf文件,支持带一级子目录的
158+
每章内容分别放在不同的目录下,目录名为章节名
159+
最终生成的pdf,按章节名生成书签
160+
'''
161+
import os, sys, codecs
162+
from PyPDF2 import PdfFileReader, PdfFileWriter, PdfFileMerger
163+
import glob
164+
165+
def getFileName(filepath):
166+
'''获取当前目录下的所有pdf文件'''
167+
file_list = glob.glob(filepath+"/*.pdf")
168+
# 默认安装字典序排序,也可以安装自定义的方式排序
169+
# file_list.sort()
170+
return file_list
171+
172+
def get_dirs(filepath='', dirlist_out=[], dirpathlist_out=[]):
173+
# 遍历filepath下的所有目录
174+
for dir in os.listdir(filepath):
175+
dirpathlist_out.append(filepath + '\\' + dir)
176+
return dirpathlist_out
177+
178+
def merge_childdir_files(path):
179+
'''每个子目录下合并生成一个pdf'''
180+
dirpathlist = get_dirs(path)
181+
if len(dirpathlist) == 0:
182+
print("当前目录不存在子目录")
183+
sys.exit()
184+
for dir in dirpathlist:
185+
mergefiles(dir, dir)
186+
187+
def mergefiles(path, output_filename, import_bookmarks=False):
188+
#遍历目录下的所有pdf将其合并输出到一个pdf文件中,输出的pdf文件默认带书签,书签名为之前的文件名
189+
#默认情况下原始文件的书签不会导入,使用import_bookmarks=True可以将原文件所带的书签也导入到输出的pdf文件中
190+
merger=PdfFileMerger()
191+
filelist=getFileName(path)
192+
if len(filelist)==0:
193+
print("当前目录及子目录下不存在pdf文件")
194+
sys.exit()
195+
for filename in filelist:
196+
f=codecs.open(filename,'rb')
197+
file_rd=PdfFileReader(f)
198+
short_filename=os.path.basename(os.path.splitext(filename)[0])
199+
if file_rd.isEncrypted==True:
200+
print('不支持的加密文件:%s'%(filename))
201+
continue
202+
merger.append(file_rd,bookmark=short_filename,import_bookmarks=import_bookmarks)
203+
print('合并文件:%s'%(filename))
204+
f.close()
205+
#out_filename=os.path.join(os.path.abspath(path),output_filename)
206+
merger.write(output_filename+".pdf")
207+
print('合并后的输出文件:%s'%(output_filename))
208+
merger.close()
209+
210+
if __name__ == "__main__":
211+
# 每个章节一个子目录,先分别合并每个子目录文件为一个pdf,然后再将这些pdf合并为一个大的pdf,这样做目的是想生成每个章节的书签
212+
# 1.指定目录
213+
# 原始pdf所在目录
214+
path = "E:\RZF\RenZhengfei-master\ALL-pdf"
215+
# 输出pdf路径和文件名
216+
output_filename = "E:\RZF\RenZhengfei-master"
217+
218+
# 2.生成子目录的pdf
219+
# merge_childdir_files(path)
220+
221+
# 3.子目录pdf合并为总的pdf
222+
mergefiles(path, output_filename)
223+
```
224+
225+
226+
227+
整个程序一目了然,把 wk_path 修改成你自己的 wkhtmltopdf 安装路径。file_path 是你的 html 文件路径,而 save_path 就是你 pdf 文件保存的地方。
228+
229+
230+
231+
### **4、总结**
232+
233+
整个过程用到了两个函数文件,文章已经把所有的源码全部贴了出来,大家复制到本地就可以使用了,记得把相应的库安装好。
234+
235+
236+
237+
参考:<https://www.cnblogs.com/hankleo/p/10911810.html>

0 commit comments

Comments
 (0)