搞定 PDF"膨胀"难题:Python + Java 的超实用压缩秘籍
哈喽小伙伴们!今天想和大家唠唠 PDF 文件压缩那些事儿,这可是办公族的常遇到的"头疼事"。就拿我上次帮朋友处理合同文件来说吧,一份超长超高清的合同 PDF,动辄几百兆,发邮件老是提示附件太大,存到云盘也占地方得心疼。我琢磨着,要是能把这 PDF"瘦身"一下,那该多好呀!
为啥要用 Python + Java 来搞定 PDF 压缩?
先和大家说说,为啥不单独用 Python 或 Java 呢?其实吧,光靠 Python 现有的压缩包,效果真心不太理想,压缩后的文件还是有点"胖"。而 Java 里有个叫 spire.pdf.free
的库,压缩 PDF 那叫一个厉害,能把图像啥的压缩得恰到好处。可它也有个小缺点,就是处理 PDF 超过 10 页就有点"吃力"(需要收费)。所以呀,我琢磨着先把 PDF 拆开,再用 Java 压缩,最后再把它们合起来,这就引出了我们今天的"三步走"策略啦!
第一步:用 Python 给 PDF"分家"
这第一步,就是把一个大 PDF 文件拆成几个小块儿。我选了 Python 的 PyPDF2 库,这玩意儿操作 PDF 简单又方便。下面就是代码啦:
python
import os
from PyPDF2 import PdfReader, PdfWriter
def split_pdf(input_pdf_path, output_folder, pages_per_split=10):
# 打开输入的 PDF 文件
with open(input_pdf_path, 'rb') as file:
reader = PdfReader(file)
num_pages = len(reader.pages)
split_count = 0
for i in range(0, num_pages, pages_per_split):
writer = PdfWriter()
end = min(i + pages_per_split, num_pages)
# 将页面添加到新的 PDF 写入器中
for page_num in range(i, end):
writer.add_page(reader.pages[page_num])
# 生成输出文件路径
output_filename = os.path.join(output_folder, f'split_{split_count}.pdf')
split_count += 1
# 保存拆分后的 PDF 文件
with open(output_filename, 'wb') as output_file:
writer.write(output_file)
if __name__ == "__main__":
# 替换为你的输入 PDF 文件路径
input_pdf = r'C:\Users\bugMaker\Desktop\untitled\input.pdf'
# 替换为你想要保存拆分后文件的文件夹路径
output_folder = r'C:\Users\bugMaker\Desktop\pdf'
# 创建输出文件夹(如果不存在)
if not os.path.exists(output_folder):
os.makedirs(output_folder)
split_pdf(input_pdf, output_folder)
这段代码呢,就是把 PDF 按照每 10 页一组拆开,放到指定的文件夹里。你要是觉得 10 页不合适,改改 pages_per_split
这个参数就行啦!是不是超简单?就像给文件做了一次"分工",把大任务变成小任务,方便后面处理。
第二步:让 Java 给 PDF"瘦身"
拆完之后,就轮到 Java 出场啦!我用的是 spire.pdf.free
库,它对 PDF 里的图像啥的压缩效果超棒。看代码:
java
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.pdf.free</artifactId>
<version>5.1.0</version>
</dependency>
java
package org.example;
import com.spire.pdf.PdfCompressionLevel;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.exporting.PdfImageInfo;
import com.spire.pdf.graphics.PdfBitmap;
public class CompressPDFImage {
public static void main(String[] args) {
// 创建 PdfDocument 类的对象
PdfDocument doc = new PdfDocument();
// 加载 PDF 文档
doc.loadFromFile("C:\\Users\\bugMaker\\Desktop\\untitled1\\input.pdf");
// 将增量更新设置为false
doc.getFileInfo().setIncrementalUpdate(false);
// 将压缩级别设置为最佳
doc.setCompressionLevel(PdfCompressionLevel.Best);
// 循环遍历文档中的页面
for (int i = 0; i < doc.getPages().getCount(); i++) {
// 获取特定页面
PdfPageBase page = doc.getPages().get(i);
// 获取每个页面的图像信息集合
PdfImageInfo[] images = page.getImagesInfo();
// 遍历集合中的项目
if (images != null && images.length > 0)
for (int j = 0; j < images.length; j++) {
// 获取指定图像
PdfImageInfo image = images[j];
PdfBitmap bp = new PdfBitmap(image.getImage());
// 设置压缩质量,数字越小,压缩越彻底,但是小心颜色失真哦,太小的话,会使图片灰度化
bp.setQuality(8);
// 用压缩后的图片替换原始图片
page.replaceImage(j, bp);
}
}
// 保存文件
doc.saveToFile("output.pdf");
doc.close();
}
}
这段代码呢,就是把拆开的 PDF 文件里的图像质量调低一点(当然也不会太低,保证能看清),然后把压缩后的图像换上去,这样 PDF 就能"瘦身"啦!是不是很神奇?就像给文件做了个"减肥操",把不必要"脂肪"都减掉啦!
第三步:用 Python 把 PDF 合体
最后一步,就是把压缩后的 PDF 小块儿再合起来。还是用 Python 的 PyPDF2 库,方便快捷。看代码:
python
from PyPDF2 import PdfReader, PdfWriter
import os
def merge_pdfs(input_folder, output_file):
pdf_writer = PdfWriter()
# 获取文件夹中所有的 PDF 文件并按名称排序
pdf_files = [f for f in os.listdir(input_folder) if f.lower().endswith('.pdf')]
pdf_files.sort()
for pdf_file in pdf_files:
pdf_path = os.path.join(input_folder, pdf_file)
pdf_reader = PdfReader(pdf_path)
for page in pdf_reader.pages:
pdf_writer.add_page(page)
with open(output_file, 'wb') as out:
pdf_writer.write(out)
if __name__ == "__main__":
# 修改这里的路径为包含要合并的 PDF 文件的文件夹路径
input_folder = r'C:\Users\bugMaker\Desktop\新建文件夹'
# 修改这里的路径为合并后的输出文件路径
output_file = r'合并后的输出文件路径.pdf'
merge_pdfs(input_folder, output_file)
这段代码就是把拆开的 PDF 按顺序合到一起,生成一个新的 PDF 文件。就像把拆开的乐高积木再拼成一个完整的玩具,最后就得到一个"瘦身"成功又完整的 PDF 啦!
总结一下这个超实用套路
用 Python 把 PDF 拆开,再用 Java 给它"瘦身",最后再用 Python 把它合起来,这个方法是不是很绝?以后要是再遇到 PDF 文件太大这种烦心事,就可以用这个套路轻松解决啦!而且呢,这个方法也可以根据自己的需要调整,比如在 Java 压缩的时候,把图像质量调高一点或者调低一点,或者在 Python 拆分的时候,把页数改改,这样就能灵活应对各种情况啦!是不是感觉办公技能又提升啦?赶紧试试吧!