2025年12月的四级考试刚结束,网上就开始流传第1套真题的PDF版本。我拿到手的那份一共9页,文件体积不算大,但接下来的操作让很多人抓狂:想复制几段文字出来复习,复制出来全是乱码;想转成Word改一改格式,排版散成一团;好容易准备打印,打出来又发现只有页面左侧有内容。这份9页的PDF几乎把PDF处理里最常见的坑都踩了个遍。这篇文章就以这份“2025年12月四级真题第1套PDF(共9页)”做样本,从为什么PDF这么难编辑开始,到文本提取、格式转换、页面编辑、打印排障、乱码修复,把一套完整的处理流程讲清楚。无论你手头是考试真题、电子教材、报销发票还是设计图纸,这套方法都能直接照搬。
1. 这份9页PDF的身份信息,先花30秒看清楚
1.1 从文件属性判断文本版还是扫描版
拿到PDF之后,我习惯先看三个东西:文件大小、页数、页面尺寸。右键文件属性就能看到大小和页数,但页面尺寸和PDF版本信息藏得更深一点,需要另外查。
在Windows上如果装了Adobe Acrobat Reader,按Ctrl+D可以打开文档属性,基本信息都在里面。想更快一点,可以用命令行工具pdfinfo,它来自poppler-utils:
bash复制pdfinfo "2025年12月四级真题第1套.pdf"
输出会包含Pages、Page size、PDF version、Metadata等信息。不想装额外工具的话,用Python的pypdf库也行:
python复制from pypdf import PdfReader
reader = PdfReader("2025年12月四级真题第1套.pdf")
print("页数:", len(reader.pages))
print("PDF版本:", reader.pdf_header)
page = reader.pages[0]
print("页面尺寸(pt):", page.mediabox.width, page.mediabox.height)
为什么要先看文件大小?因为这是判断“文本版PDF”和“扫描版PDF”最便宜的指标。纯文本型的PDF,一页包含的主要是文字编码和字体子集,通常只有10到50KB;而扫描版是整页图片,一页落在200KB到1MB都很正常。一份9页的文本版真题,总大小一般在几百KB;要是超过3MB,大概率是扫描图片或者嵌入了大量高清图片。
判断版本这件事直接决定后续走哪条路。文本版可以直接提取文字;扫描版必须走OCR,甚至某些扫描件连OCR都救不了,只能手动校对。用表格来看更直观:
| 类型 | 典型文件大小 | 能否选中文字 | 能否直接提取文本 | 推荐处理方式 |
|---|---|---|---|---|
| 文本版 | 每页10-50KB | 能 | 能 | pdfplumber / PyMuPDF 直接提取 |
| 扫描版 | 每页200KB以上 | 不能 | 不能 | 渲染为图片后OCR |
| 文字+图片混合 | 视图片数量而定 | 部分能 | 能但排版可能乱 | 提取文本加图片分离处理 |
1.2 页面尺寸和方向:打印事故的第一源头
PDF页面尺寸这个概念很多人忽略了,直到打印时才出问题。PDF的单位是磅(point),1英寸等于72磅,A4纸的尺寸是595 x 842磅,换算成厘米是21 x 29.7厘米。用pypdf把9页的尺寸都看一遍:
python复制for i, page in enumerate(reader.pages):
w = float(page.mediabox.width)
h = float(page.mediabox.height)
print(f"第{i+1}页: {w:.1f} x {h:.1f} pt(约 {w/72*2.54:.1f} x {h/72*2.54:.1f} cm)")
如果所有页面都接近595 x 842,说明是标准A4,直接打印基本没问题。但很多从报名网站或考试系统导出的PDF,页面尺寸可能是自定义的,比如1000 x 800磅,或者每一页尺寸都不一样。这种文件如果按“实际大小”打印,内容会被裁掉;按“适合页面”打印,又可能留出大片空白。所以打印之前先做一次页面尺寸体检,能避开后面很多麻烦。
1.3 9页试卷的页序检查:翻一遍只花10秒
很多人拿到PDF就直接复制或者转换,我建议先花10到30秒把9页从头到尾过一遍。这不是浪费时间,而是确认三件事:页序是否正常、有没有缺页、有没有重复页。
我从别人手里拿到过的考试类PDF,经常出现第3页和第4页顺序颠倒、第7页重复出现了两次、最后一页被截成半页的情况。这些用任何自动化工具都很难提前发现,人工翻一遍最靠谱。PDF阅读器左侧有缩略图栏,连续滚动看缩略图比一页页翻快得多。确认这三点之后再进入解析环节,后面所有操作才是有意义的。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. PDF解析:把文字和图片从页面里“抠”出来
2.1 PDF为什么“看得见摸得着却不好编辑”
要做解析,先得明白PDF的内部结构。PDF可以理解成一张画布,页面上的每个元素都记录着自己在这张画布上的精确坐标。文字不是像Word那样按段落存储的,而是以“内容流”的方式,记录着一串操作指令:在(x, y)位置用某个字体显示字符串“Hello”,紧接着在另一个坐标画一条线,或者放一张图片。
经典的显示文本操作符是Tj和TJ,它们后面跟的字符串才是你看到的文字内容。问题是,这个字符串的编码不一定对应Unicode,它可能只是字体内部的一个字形编号。PDF阅读器能通过字体资源里的CMap表把字形显示出来,但如果没有ToUnicode映射,复制出来的就是乱码。这就是为什么很多PDF“看着正常,一复制就原形毕露”。
把PDF结构比作家具会更清楚:一台做好的实木椅子送到你面前,你看到的是椅子的形态,但你想把它改回一堆木材,再重新拼成一张桌子,这就非常困难。PDF解析就是从已成型的家具里逆向推断哪里是腿、哪里是背板,试图理解原本的设计意图。
2.2 文本型PDF:用pdfplumber提取正文和表格
判断出这份9页的PDF是文本版之后,我第一个工具是pdfplumber。它基于PDFMiner,能按照坐标重构文本顺序,而且对表格的提取比PyPDF2友好得多。
安装后直接跑:
python复制import pdfplumber
with pdfplumber.open("2025年12月四级真题第1套.pdf") as pdf:
print("总页数:", len(pdf.pages))
for i, page in enumerate(pdf.pages):
text = page.extract_text()
print(f"----- 第{i+1}页 -----")
print(text[:500] if text else "[本页没有提取到文本]")
这里有个需要留意的点:extract_text()是按坐标从下到上、从左到右重建文本顺序的。真题阅读部分经常是左右分栏排版,直接提取出来的文字可能会把左栏和右栏的内容混在一起。遇到这种情况,可以调整x_tolerance参数,它表示同一行里相邻字符的最大水平间距,适当调大能让左右栏被识别为不同文本块。
提表格用extract_table():
python复制table = page.extract_table()
if table:
for row in table:
print(row)
但真题PDF里单一的表格不多,大部分是文字题和图片题,所以表格提取在试卷场景里不是重点。如果你的PDF是财务报表、调查问卷,这个功能就非常值钱了。
2.3 图片型PDF:先用PyMuPDF切片图片,再走OCR
如果pdfplumber提取出来的text全是None,或者复制文字时根本选不中,那基本可以断定这是扫描版。扫描版PDF的每一页本质上是一张图片,处理思路是先把页面渲染成高分辨率图片,再交给OCR引擎识别文字。
用PyMuPDF(import名是fitz)来做页面渲染和图片提取,效率非常高:
python复制import fitz
doc = fitz.open("2025年12月四级真题第1套.pdf")
# 把每一页渲染成2倍分辨率的PNG图片
for page in doc:
pix = page.get_pixmap(matrix=fitz.Matrix(2, 2))
pix.save(f"page-{page.number+1}.png")
# 提取页面内嵌的每一张图片
for page in doc:
for img in page.get_images(full=True):
xref = img[0]
pix = fitz.Pixmap(doc, xref)
# CMYK图片直接存PNG会出错,需要转成RGB
if pix.colorspace and pix.colorspace.name == "CMYK":
pix = fitz.Pixmap(fitz.csRGB, pix)
pix.save(f"image-xref-{xref}.png")
渲染成图片之后,OCR就看你的环境了。Tesseract是老牌开源方案,需要单独下载语言包:
bash复制tesseract page-1.png out -l chi_sim
Python里可以用pytesseract调:
python复制import pytesseract
from PIL import Image
text = pytesseract.image_to_string(Image.open("page-1.png"), lang="chi_sim")
print(text)
如果英文和中文混排,语言参数可以写成lang="chi_sim+eng"。我实际测试下来,300DPI以上的渲染图识别准确率才有保证,2倍缩放大约能到144DPI,比较模糊的原件建议开到3倍以上。OCR不是万能的,遇到加粗黑体、带下划线、表格线压字的题目,识别结果会烂到没法看。
2.4 解析时常见的坑:分栏混排、隐藏文字、字体编码
解析PDF时最容易踩的坑有三个。
第一个是分栏混排。前面提到过,真题阅读题左右两栏,pdfplumber提取时可能把两栏混成一段,想恢复阅读顺序就得人工介入。更好的办法是先通过page.columns或其他版面对齐工具做分栏检测,但效果取决于版面复杂度,没有银弹。
第二个是隐藏文字。有些试卷PDF为了让用户只能看不能复制,会把一层透明文字盖在图片上,或者用白色字体写出干扰内容。用pdfplumber能看到这些隐藏字符,但打印时看不到;反过来,有些文字被转成图片后,又不参与文本提取。这两种情况都要靠OCR兜底。
第三个就是字体编码问题。这一步在第六章还会详细展开。简单说,如果提取出来的是乱码,别怀疑python库出了问题,是PDF内部根本没存Unicode映射。这时唯一有效的办法就是渲染成图片再OCR。
3. 格式转换:PDF转Word、网页、图片的正确姿势
3.1 PDF转Word总乱版,根子在“固定布局 vs 流式布局”
我在多个群里看到有人抱怨“PDF转Word怎么转都是乱的”。这不是工具不行,是两种文档模型天然不兼容。
Word这类文字处理软件的底层是流式布局:文字按段落顺序排列,遇到换行自然流动,修改一个词,后面的内容自动重排。PDF是固定布局:每个字符的坐标都写死了,它只关心“显示在哪”,不关心“这段是不是一个段落”。转换器要做的事情,是从固定坐标反推段落结构、标题层级、列表关系,再把它们塞回流式文档里。这个过程本质上是在猜,猜错了排版就崩。
一份9页的四级真题PDF,包含多栏文本、题号、图片、音量波形图、表格线,转换器能猜对一半就不错了。我能给的最实用的建议是:如果目标只是拿到里面的文字,用文本提取比直接转Word可靠得多;如果一定要生成可编辑的Word,第一步先把PDF转成纯文本或Markdown,手工清理一遍后再重新排版,最终的版式比任何自动转换都干净。
3.2 本地转换工具的选型:Adobe、WPS、LibreOffice怎么选
我在不同场景下用过的PDF转Word工具,各有取舍:
| 工具 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| Adobe Acrobat Pro | 转换质量最高,保留版式能力强 | 付费 | 对排版要求高的正式文件 |
| WPS Office | 中文支持好,国内下载方便 | 免费额度有限,会员引导强 | 轻度转换,日常够用 |
| LibreOffice Draw | 开源免费,本地处理 | PDF版面复杂时还原一般 | 不想用云服务、注重隐私 |
| 在线工具(Smallpdf等) | 免安装,操作简单 | 文件大小限制、水印、隐私风险 | 不敏感文件、应急场景 |
我的习惯是本地优先。特别是涉及发票、合同这类敏感文档,往在线工具上传等于把隐私交给别人保管。热搜里有个词叫“pdf发票 本地对账”,说的正是这个场景:电子发票本身就是带版式的PDF,完全可以用pdfplumber把发票号和金额字段提取出来,拿到本地做Excel对账,根本不需要上传到任何网站。
3.3 用Microsoft Print to PDF把“打印”变成“生成PDF”
很多人的电脑上找不到“Microsoft Print to PDF”这个打印机。它是Windows自带的虚拟打印机,不需要下载驱动,只需要在系统设置里把它启用。
启用路径是:设置 → 应用 → 可选功能 → 添加功能 → 搜索“Microsoft Print to PDF” → 安装。如果找不到这个选项,说明系统是精简版,可以尝试在“打印机和扫描仪”里手动添加打印机,选择“通过手动设置添加本地打印机或网络打印机”,端口选“使用现有端口:PORTPROMPT”,驱动列表里找“Microsoft Print to PDF”。装好之后,任意能打印的应用里按Ctrl+P,选择这台打印机,就能输出一份新的PDF。
这个功能最实用的场景有两个。一是把网页、图片、课件等不可编辑的内容转成PDF;二是给有问题的PDF“洗一遍”。有些PDF文件内部结构混乱,在浏览器里显示正常,但打不开或提取失败,把它重新“打印”成一份新PDF,有时能顺带修复不少问题。
3.4 免费在线工具的局限和本地化替代
在线PDF工具处处是坑:免费版限制文件不超过一定大小,页数超过3页就要求付费;就算转出来了,右上角盖一个水印;更麻烦的是,上传到别人的服务器,等于把文档内容交出去了。
我的建议是找一套本地工具组合取代在线工具:pdfplumber做解析,PyMuPDF做图片和渲染,pypdf做拆合,LibreOffice做格式转换,Tesseract做OCR。这一套组合应付日常99%的需求都没有问题。如果你还要把Markdown转成PDF,可以用pandoc配合LaTeX或weasyprint;想在前端网页弹窗里预览PDF,可以用PDF.js渲染到Canvas而不是直接丢一个iframe;自建NAS想要在线预览,可以用Docker跑OnlyOffice Docs。每个场景都有成熟的开源方案,离开在线PDF网站大家照样能活。
4. 编辑与组装:拆页、合并、加水印、修复缩略图
4.1 pypdf实现拆页、挑页、合并
一份9页的PDF有时不需要全部内容,只要后面几页翻译题,或者想把零散发来的几份资料合并成一份完整复习包。这些操作用pypdf就能完成,而且完全本地执行。
拆出指定页面:
python复制from pypdf import PdfReader, PdfWriter
reader = PdfReader("2025年12月四级真题第1套.pdf")
writer = PdfWriter()
for idx in [7, 8]: # 取第8页和第9页
writer.add_page(reader.pages[idx])
with open("translate-pages.pdf", "wb") as f:
writer.write(f)
合并三个PDF:
python复制from pypdf import PdfWriter
writer = PdfWriter()
for filename in ["听力部分.pdf", "阅读部分.pdf", "翻译写作部分.pdf"]:
reader = PdfReader(filename)
for page in reader.pages:
writer.add_page(page)
with open("merged-exam.pdf", "wb") as f:
writer.write(f)
如果觉得写代码麻烦,可以装一个pdfarranger,它把PDF页面像拼图一样展示,支持拖拽排序、旋转、删除、合并,是可视化处理PDF页面的利器。pypdf适合批量、可复现的操作,pdfarranger适合鼠标点两下就完事的小需求,两者互补。
4.2 给整套试卷加水印和页码
网上下载的真题PDF常带着“仅供学习交流”的水印,或者你自己想在分享出去之前加个名字水印。pypdf的merge_page可以把一个水印PDF叠加到目标页面上:
python复制from pypdf import PdfReader, PdfWriter
watermark = PdfReader("watermark.pdf").pages[0]
reader = PdfReader("2025年12月四级真题第1套.pdf")
writer = PdfWriter()
for page in reader.pages:
page.merge_page(watermark)
writer.add_page(page)
with open("output-with-watermark.pdf", "wb") as f:
writer.write(f)
注意水印PDF的页面尺寸要和目标PDF一致,否则merge_page会按坐标直接叠放,大小不匹配的话水印位置会跑偏。想加页码的话,可以用reportlab先生成一个只有页码数字的PDF,再用同样的方式合并到每一页。我通常把页码放在页脚偏右的位置,字号11号左右,比Word自动页码明显但不抢眼。
4.3 Windows下PDF缩略图不显示的补丁式修复
很多人发现Windows资源管理器里PDF文件只显示一个图标,不显示页面缩略图。这个问题对应的解决方案还挺微妙,原因通常是三者之一:
- 资源管理器的“始终显示图标,从不显示缩略图”被勾选了。检查路径:文件夹选项 → 查看 → 取消勾选“始终显示图标,从不显示缩略图”。
- 系统缺少PDF缩略图预览处理器。装上Adobe Acrobat Reader DC后,它会在注册表里注册预览Handler,缩略图就能正常显示。
- 缩略图缓存损坏。用磁盘清理里面的“缩略图”项,或者执行
ie4uinit.exe -show重建图标缓存。
如果装了Adobe Reader还是不行,可以试试第三方缩略图组件,比如sagethumbs。这类组件被戏称为“pdf缩略图补丁”,本质上是往Windows注册表里加一个COM接口,让资源管理器知道怎么画PDF预览。装完之后记得重启资源管理器,设置立即生效。
5. 打印实测:为什么9页PDF打出来“只剩半边”
5.1 打印前的页面尺寸体检
打印PDF最让人崩溃的瞬间,是预览时一切正常,纸出来之后内容被切掉一半。这种问题十有八九出在页面尺寸和缩放设置上。
先用前面第一章的pypdf脚本检查所有页面的mediabox尺寸。如果页面宽度大于实际A4宽度,打印机又处“实际大小”模式,那超出纸张边界的部分就会被直接裁掉。PDF阅读器的打印对话框里通常有“适合可打印区域”“缩小以适合页面”“实际大小”三个选项,遇到大页面打印机选“缩小以适合页面”基本能解决。
有些专业设计软件导出的PDF,页面里还包含TrimBox、CropBox等裁剪框信息。Acrobat在打印时默认按“裁剪框”来理解页面范围,如果裁剪框比实际内容小,打印出来就会缺边。这时需要在Acrobat的打印设置里把“页面缩放”改成“自定义比例”,或者用pypdf检查一下cropbox:
python复制for i, page in enumerate(reader.pages):
print(i + 1, "mediabox:", page.mediabox, "cropbox:", page.cropbox)
如果cropbox明显比mediabox小,内容确实会被裁剪。这类问题在广告设计稿、PCB原理图导出的PDF里特别常见,热搜里的“ad20导出原理图pdf只有部分区域”就是典型的cropbox和实际页面尺寸不匹配。
5.2 部分区域打印不出来的排查链路
我按自己遇到过的案例,把“打印只有部分区域”的排查顺序整理出来:
- 先确认PDF页面尺寸是不是标准A4。不是的话,用“适合页面”打印再试。
- 确认页面方向。横向页面打印到纵向A4会缩小到看不清,或者出现左右大面积留白。
- 检查打印机的“缩放”设置。有些打印机驱动默认设置了“适合边框”,但“边框”的计算方式和阅读器不同,导致边缘被切。
- 检查PDF是否有CropBox。有的话,用Acrobat的“设置页面框”把裁剪框清除或重置为实际内容范围。
- 如果还不行,把这份PDF用Microsoft Print to PDF重新输出一份A4尺寸的PDF,再去打印。这一步相当于把不规范的页面元数据“洗”掉。
这套链路我验证过很多次,95%的打印缺边问题都能在第三步或第五步解决。整个过程不需要动原文件,最多生成一个打印副本,放心试。
5.3 网页预览PDF和网页内嵌PDF的下载打印
现在很多平台不再提供PDF附件下载,而是在网页里嵌入一份PDF预览。想拿下来打印,第一反应是Ctrl+P,其实不一定对。
网页里的PDF通常有两种存在方式:一种是直接用PDF文件地址打开,浏览器自带的PDF查看器展示,这种最简单,地址栏就是文件链接,右键保存就行;另一种是嵌在HTML的iframe或object标签里,地址藏在页面源码中。可以按F12打开开发者工具,找到Embedded的src属性,通常就是PDF的真实URL,直接在新标签打开再保存。
如果网站用Blob URL动态加载PDF,src可能是一长串blob:https://...,这时候从Network面板找到PDF文件的请求,右键“另存为”即可。下载成功后,再按第五章的方法做页面体检和打印设置,应该是花不了多少时间的。
5.4 给开发者的两句提醒:弹窗预览和NAS预览
有开发需求的话,这里顺带提两个点。
Element UI的Dialog弹窗里加载PDF,不要直接把整个PDF文件塞给后端做转换,前端用<iframe :src="pdfUrl">就能实现预览,但移动端体验很差。更好的做法是用PDF.js把PDF渲染成Canvas,再做分页滑动。你的后端只需要提供一个能正常响应Range请求的静态文件接口,别让大PDF一次性加载进内存。
自己组了NAS、想在浏览器里预览PDF的朋友,可以不用装正版Adobe全家桶。用Docker部署OnlyOffice Docs,配合Alist的文件列表功能,在网页里点击PDF文件时调用OnlyOffice的预览地址,效果和WPS在线预览差不多,而且数据完全在自己服务器上。这套方案对隐私敏感的资料非常友好。
6. 中文乱码与转曲:字体问题的最后一块拼图
6.1 能显示、复制乱码的真相
PDF里复制文字出来全是乱码,这个问题几乎没有一步到位的修复方案,因为它属于“先天缺陷”。PDF文档里存储文字时,会建立一个“字形编号到字符显示”的映射关系,如果文档创建工具没有写入ToUnicode CMap表,阅读器就只认识字形编号,不认识这些编号对应的Unicode字符。于是显示没问题,复制时却拼不出正确字符。
这类PDF多见于早期国产Word插件导出的文件、某些CSDN下载的试卷扫描版、自研软件生成的报表。想让它“能复制”,唯一可靠的方法是OCR重打一层文本,或者用Acrobat的“增强扫描”功能识别后添加文本层。普通用户不建议手动编辑PDF内部结构去补ToUnicode表,投入产出比太低。
6.2 什么时候必须转曲,怎么转
转曲(outline)是把所有文字转换成矢量轮廓线框,不再依赖任何字体文件。转曲后的PDF在任何设备上打开都是一模一样的形状,不会因为缺字体而替换成系统默认字体,也不会出现乱码。
如果你只是打印普通A4文档和学习资料,不需要转曲。真正必须转曲的场景是印刷:广告公司出画册、名片、宣传单,文件发到印刷厂,印刷机那套系统里不一定安装了你的字体,字体缺失就会替换成相近字体,版式分分钟崩掉。试卷类PDF如果只是电子分享,转不转曲并不影响阅读。
转曲最标准的方法是用Adobe Acrobat Pro:打开PDF后进入“印前检查”工具,选择“将文本转换为轮廓”,确认后保存。没有Acrobat Pro的话,用InDesign或Illustrator打开PDF再导出时勾选“转为轮廓”也能达到一样效果。需要提醒的是,转曲之后的PDF文字不可搜索、不可编辑,文件体积还会变大,属于“用可编辑性换可靠性”的操作,想清楚再动手。
6.3 字体嵌入检查与统一修复
印刷或跨设备分享PDF之前,建议检查一下字体有没有真正嵌入。Acrobat的文件属性 → 字体列表里,未嵌入的字体后面会标注“未嵌入”三个字。用PyMuPDF也能自动检查:
python复制import fitz
doc = fitz.open("2025年12月四级真题第1套.pdf")
for page in doc:
for font in page.get_fonts():
print(font)
get_fonts返回的元组至少包含xref、ext、type、basefont等字段,重点看basefont前面的字体名以及ext是不是“Type0”或“TrueType”。如果发现某些字体未嵌入,可以用Ghostscript重新处理一份:
bash复制gswin64c -dNOPAUSE -dBATCH -dSAFER \
-sDEVICE=pdfwrite \
-dPDFSETTINGS=/prepress \
-dEmbedAllFonts=true \
-dSubsetFonts=true \
-o output.pdf "2025年12月四级真题第1套.pdf"
这段命令的作用是把所有字体嵌入并精简子集,输出一份新的PDF。严格来说这不能解决“复制乱码”的问题,但能解决“换设备打开字变样”的问题。很多人把这两个问题混为一谈,排查时容易走弯路。
7. 我的处理流水线和问题速查表
7.1 从拿到PDF到最终交付的固定动作
处理PDF这些年,我总结了一套固定动作,不管面对什么类型的PDF,先按这个顺序走一遍:
- 看文件属性:大小、页数、版本。
- 打开PDF,试着选中文字,判断文本版还是扫描版。
- 用pdfplumber或PyMuPDF提取需要的内容;提取不到就渲染成图片走OCR。
- 根据用途决定下一步:要编辑就提取文本重排,要合并拆分就上pypdf,要打印就先查页面尺寸。
- 输出前统一处理字体嵌入问题,避免换设备翻车。
这套流程的核心理念是“先定性,再动手”。我见过太多人一拿到PDF就丢给在线转换工具,被水印、页数限制和排版错乱折磨一整晚,最后发现那是个扫描版PDF,根本不适合直接转Word。提前花30秒做判断,比盲目试工具省时间得多。
7.2 高频问题速查表
| 症状 | 常见原因 | 快速解决 |
|---|---|---|
| PDF打开后显示乱码 | 缺少嵌入字体 | Ghostscript重新嵌入字体 |
| 复制文字是乱码 | 缺少ToUnicode映射 | 渲染成图片后OCR |
| 打印只有部分区域 | 页面尺寸或CropBox异常 | 打印时“适合页面”,或用虚拟打印机洗一遍 |
| PDF在资源管理器没有缩略图 | 预览Handler缺失 | 装Adobe Reader或第三方缩略图补丁 |
| PDF转Word排版乱 | 固定布局还原流式布局困难 | 先提取文本再手动重排 |
| 扫描版PDF不能复制文字 | 内容是图片 | OCR识别并添加文本层 |
| 在线转换有水印或限制 | 免费版限制 | 改用本地工具组合 |
| 文件太大,分享困难 | 图片分辨率过高 | 用PyMuPDF重新渲染低分辨率,或Ghostscript压缩 |
7.3 一个批量处理的示例脚本
最后附一个非常实用的脚本,把一份9页PDF拆成9个单页PDF,文件名按页码编号,适合只需要选其中某几页的场景:
python复制from pypdf import PdfReader, PdfWriter
from pathlib import Path
input_path = Path("2025年12月四级真题第1套.pdf")
out_dir = Path("split")
out_dir.mkdir(exist_ok=True)
reader = PdfReader(str(input_path))
for i, page in enumerate(reader.pages):
writer = PdfWriter()
writer.add_page(page)
out_path = out_dir / f"page-{i+1:02d}.pdf"
with out_path.open("wb") as f:
writer.write(f)
print(f"已生成: {out_path}")
把这个思路扩展一下,就能可以批量重命名、批量加水印、批量把整个文件夹内所有PDF合并成一份。命令行和Python在处理大批量PDF时优势非常明显,手动打开几十个文件再每个另存为,和一行脚本跑完,效率完全不在一个量级。
我个人处理PDF的习惯是:无论拿到什么文件,先不急着转或改,花半分钟确认它到底是文本版还是扫描版、页面实际尺寸多大,这两点直接决定后续路线。这比我一开始就到处找在线转换工具高效得多。这份9页的四级真题PDF只是个引子,换成电子教材、报销发票、设计图纸,排查思路完全一样。你按这套流程走一遍,以后再遇到奇怪的PDF,应该不会再慌。
