压缩word文件(DOCX格式)

Docx 文件转 PDF 体积过大的根本原因在于屏幕截图通常是高分辨率的无损 PNG 格式,Word 在转 PDF 时默认保留了原始像素或采用了较低的压缩率。要编程实现减小体积,最优的策略是在 Python 中读取 docx,将里面的图片进行有损压缩(如转为高质量的 JPEG 并降低分辨率),再重新保存 docx 并转为 PDF。

核心解决思路

  1. 解压 docx:docx 本质是一个 ZIP 压缩包,图片存放在 word/media/ 目录下。
  2. 编程压缩图片:使用 Python 的 Pillow 库遍历 word/media/ 中的所有图片,将其转换为体积更小的 JPEG 格式,或者按比例缩减长宽尺寸、降低质量(Quality=85)。
  3. 替换并重新打包:将压缩后的图片覆盖原文件,再转换成 PDF。

Python 编程实现方案

你可以使用 Python 的 zipfile 和 Pillow 库直接对 docx 内部的图片进行无感知瘦身,无需逐个修改 Word 对象。

1. 安装依赖库

bash

1
pip install Pillow

2. Python 压缩脚本代码

创建一个 compress_docx.py 文件:

python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import os
import zipfile
import shutil
from PIL import Image

def compress_image(image_path, quality=80, max_width=1920):
    """压缩单张图片:降低质量并限制最大宽度"""
    try:
        with Image.open(image_path) as img:
            # 如果是透明图(RGBA),转为RGB防止转JPEG报错
            if img.mode in ('RGBA', 'LA'):
                background = Image.new('RGB', img.size, (255, 255, 255))
                background.paste(img, mask=img.split()[-1])
                img = background
            elif img.mode != 'RGB':
                img = img.convert('RGB')
            
            # 限制最大宽度,防止超大截图
            if img.width > max_width:
                ratio = max_width / img.width
                new_height = int(img.height * ratio)
                img = img.resize((max_width, new_height), Image.Resampling.LANCZOS)
            
            # 保存为压缩后的 JPEG
            img.save(image_path, 'JPEG', quality=quality, optimize=True)
    except Exception as e:
        print(f"处理图片失败 {image_path}: {e}")

def optimize_docx_images(docx_path, output_path, quality=80):
    """解压docx,压缩media中的图片,再重新打包"""
    temp_dir = "temp_docx_extracted"
    if os.path.exists(temp_dir):
        shutil.rmtree(temp_dir)
        
    # 1. 解压 docx
    with zipfile.ZipFile(docx_path, 'r') as zip_ref:
        zip_ref.extractall(temp_dir)
        
    # 2. 遍历并压缩图片
    media_dir = os.path.join(temp_dir, 'word', 'media')
    if os.path.exists(media_dir):
        for filename in os.listdir(media_dir):
            if filename.lower().endswith(('png', 'jpg', 'jpeg', 'bmp', 'tiff')):
                file_path = os.path.join(media_dir, filename)
                # 针对 png 截图,统一转成更小的 jpg 压缩
                base_name, _ = os.path.splitext(filename)
                new_filename = f"{base_name}.jpg"
                new_file_path = os.path.join(media_dir, new_filename)
                
                # 如果是png,重命名或转换
                if file_path != new_file_path and os.path.exists(file_path):
                    os.remove(file_path) # 实际操作中直接用原路径保存为jpg更方便
                
                # 简化处理:直接原地用PIL处理
                compress_image(file_path, quality=quality)
                
    # 3. 重新打包为 docx
    with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zip_out:
        for foldername, subfolders, filenames in os.walk(temp_dir):
            for filename in filenames:
                file_path = os.path.join(foldername, filename)
                arcname = os.path.relpath(file_path, temp_dir)
                zip_out.write(file_path, arcname)
                
    # 4. 清理临时文件
    shutil.rmtree(temp_dir)
    print(f"优化完成!生成的新文件:{output_path}")

# 使用示例
if __name__ == '__main__':
    optimize_docx_images("input.docx", "output_compressed.docx", quality=75)

3. 将压缩后的 docx 转为 PDF

处理完 docx 后,你可以通过 Office 软件或者 Python 库(如 win32com 在 Windows 上调用 Word)将其导出为 PDF,此时的 PDF 体积会大幅缩小:

python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Windows 环境下使用 COM 组件转 PDF 示例
import win32com.client
import os

def docx_to_pdf(docx_path, pdf_path):
    word = win32com.client.Dispatch("Word.Application")
    word.Visible = False
    doc = word.Documents.Open(os.path.abspath(docx_path))
    doc.SaveAs(os.path.abspath(pdf_path), FileFormat=17) # 17 代表 PDF 格式
    doc.Close()
    word.Quit()
    print("PDF 转换成功!")