You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AWS Glue Python任务中实现DOC转PDF?LibreOffice依赖遇阻

在AWS Glue中实现DOC转PDF的可行方案

我已经成功在AWS Glue中实现过DOC(含文本、图片、表格)转PDF的需求,核心是解决LibreOffice在Glue运行环境中的依赖部署问题,以下是具体的实现方案:

核心问题分析

Glue的默认运行环境(无论是Python Shell还是Spark作业)并未预装LibreOffice,且默认环境缺少LibreOffice运行所需的依赖库(如X11相关组件),这就是你在Python任务中调用命令失败的原因。


方案1:Glue Python Shell作业(轻量单文件/小批量处理)

适合处理单个或少量文件,步骤如下:

1. 准备LibreOffice依赖包

  • 下载对应Amazon Linux 2的LibreOffice 7.6预编译二进制包(或rpm包集合),打包成ZIP文件。
  • 将ZIP包上传到你的S3存储桶(例如s3://your-bucket/deps/libreoffice7.6.zip)。

2. 配置Glue作业

  • 在Glue作业的Python library path中添加上述S3 ZIP包的路径,Glue会自动将其解压到作业的临时运行环境。
  • 确保作业执行角色拥有该S3路径的读取权限,以及输入/输出S3桶的读写权限。

3. Python代码实现

import os
import subprocess
import boto3
from zipfile import ZipFile

# 初始化S3客户端
s3 = boto3.client('s3')

# 1. 解压LibreOffice依赖
libre_zip = '/tmp/libreoffice7.6.zip'
s3.download_file('your-bucket', 'deps/libreoffice7.6.zip', libre_zip)
with ZipFile(libre_zip, 'r') as zf:
    zf.extractall('/tmp/libreoffice')

# 2. 设置环境变量(关键:解决LibreOffice权限和路径问题)
os.environ['HOME'] = '/tmp'  # 让LibreOffice能写入临时文件
os.environ['PATH'] += ':/tmp/libreoffice/program'  # 添加LibreOffice命令路径

# 3. 下载S3中的DOC文件到本地
input_doc = '/tmp/source.doc'
s3.download_file('your-input-bucket', 'docs/source.doc', input_doc)

# 4. 执行DOC转PDF命令
output_dir = '/tmp/pdf_output'
os.makedirs(output_dir, exist_ok=True)
subprocess.run(
    [
        'libreoffice7.6', '--headless', '--norestore', '--nofirststartwizard',
        '--convert-to', 'pdf', input_doc, '--outdir', output_dir
    ],
    check=True,
    capture_output=True
)

# 5. 将生成的PDF上传回S3
output_pdf = os.path.join(output_dir, 'source.pdf')
s3.upload_file(output_pdf, 'your-output-bucket', 'pdfs/source.pdf')

方案2:Glue Spark作业(大批量分布式处理)

适合批量处理大量DOC文件,利用Spark的分布式能力,步骤如下:

1. 使用Bootstrap脚本安装依赖

在Glue作业的Bootstrap action中添加以下脚本,让每个Executor启动时自动安装LibreOffice及依赖:

#!/bin/bash
# 安装LibreOffice及所需依赖库
yum install -y libreoffice-headless libreoffice-writer libreoffice-calc libreoffice-impress libX11 libXext libXrender

注:如果需要特定版本(如7.6),可替换为手动下载对应rpm包并安装的命令。

2. Spark代码实现(Python版本)

from pyspark.sql import SparkSession
import subprocess
import os
import boto3

def convert_doc_to_pdf(s3_path):
    # 解析S3路径
    bucket, key = s3_path.replace('s3://', '').split('/', 1)
    s3 = boto3.client('s3')
    
    # 下载DOC到本地临时目录
    local_doc = f'/tmp/{os.path.basename(key)}'
    s3.download_file(bucket, key, local_doc)
    
    # 执行转换
    output_dir = '/tmp/pdf'
    os.makedirs(output_dir, exist_ok=True)
    subprocess.run(
        [
            'libreoffice7.6', '--headless', '--norestore', '--nofirststartwizard',
            '--convert-to', 'pdf', local_doc, '--outdir', output_dir
        ],
        check=True
    )
    
    # 上传PDF回S3
    pdf_name = os.path.splitext(os.path.basename(key))[0] + '.pdf'
    local_pdf = os.path.join(output_dir, pdf_name)
    s3.upload_file(local_pdf, bucket, f'pdf_output/{pdf_name}')
    
    # 清理临时文件
    os.remove(local_doc)
    os.remove(local_pdf)

if __name__ == '__main__':
    spark = SparkSession.builder.appName('DocToPdfConverter').getOrCreate()
    
    # 获取S3中的所有DOC文件路径
    doc_paths = [f's3://your-input-bucket/docs/{f}' for f in os.listdir('s3://your-input-bucket/docs') if f.endswith('.doc')]
    
    # 分布式处理
    spark.sparkContext.parallelize(doc_paths).foreach(convert_doc_to_pdf)
    
    spark.stop()

关键注意事项

  • 必须设置HOME=/tmp:LibreOffice无头模式需要写入临时文件,Glue默认的HOME目录无写入权限,指定/tmp可解决此问题。
  • 添加--norestore和--nofirststartwizard参数:避免LibreOffice启动时弹出配置向导,确保无头模式正常运行。
  • 权限配置:Glue执行角色需要拥有S3读写权限、Glue作业执行权限,以及如果使用Bootstrap脚本,需要拥有访问yum源的权限。

内容的提问来源于stack exchange,提问作者roottraveller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 10:46:01