PPTX文件转为PDF或PNG图片

716 阅读2分钟

PPTX文件转为PDF或PNG图片

这里使用python作为工具,实现整个转换的过程,当然,也会涉及shell的命令。

前置条件

安装soffice

sudo apt update && sudo apt install libreoffice libreoffice-common default-jre libreoffice-java-common

安装python包PyPDF2

pip instal PyPDF2

将pptx转为PDF

这里定义一个pptx2pdf的函数,将利用libreoffice套件渲染pptx文件为pdf文件。

对应的命令行命令为: soffice --headless --convert-to pdf xxxx.pptx 然后生成一个xxx.pdf的PDF文件。

python 函数实现如下:

def pptx2pdf(source: str):
    """将来源pptx文件转为目标的pdf文件"""

    cmd = f"soffice --headless --convert-to pdf {source}"

    process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    process.wait()

    # returncode 不为 0 表示异常(非正常)退出
    if process.returncode and process.stdout:
        logger.warning(f"【{source}{cmd} 转换pptx文件失败: {process.stdout.read() !r}")
        return None

    # xxx.pptx => xxx.pdf
    target = f"{source[0:-5]}.pdf"

    logger.info(f"转换[{source}] 为 [{target}] 文件成功")

    return target

结果如下:

截图 2024-01-10 09-31-53.png

PDF文件按页分割

这一步是将一个含有多页幻灯片的PDF文件分割成多个小的PDF文件,并且每一个PDF文件都是一页幻灯片。

其中每页小PDF的命名方式为在原文件后面加一个页码的方式,比如: xxx.pdf 分割成 xxx_1.pdfxxx_2.pdf...xxx_n.pdf

python 函数实现如下:

def pdf2pages(source: str):
    """将pdf文件按页转换为多个单页面的pdf文件

    - 输入: xxx.pdf
    - 输出: [xxx_1.pdf, xxx_2.pdf, ..., xxx_n.pdf]
    """

    files: List[str] = []

    inputpdf = PdfReader(open(source, "rb"))

    # xxx.pdf => xxx
    sub_page_suffix = source[0:-4]

    for idx, pdf in enumerate(inputpdf.pages, start=1):
        output = PdfWriter()
        output.add_page(pdf)
        filename = f"{sub_page_suffix}_{idx}.pdf"

        with open(filename, "wb") as outputStream:
            output.write(outputStream)

        files.append(filename)

    return files

结果如下:

截图 2024-01-10 09-32-58.png

PDF转为PNG图片

这一步是将含有一页幻灯片的PDF文件转化为PNG图片。

对应的命令行命令为: soffice --headless --convert-to png xxxx.pdf 然后生成一个xxx.png的PNG格式的图片。

小提示: 这里可根据需求,也可以转换为其他的格式,比如,jepg。

python 函数实现如下:

def pdf2png(pdf_file: str):
    """将单个pdf页面转为png

    命令:

    soffice --headless --convert-to png <pdf_file>

    如果报错,需在服务器安装这些包

    sudo apt-get install default-jre libreoffice-java-common
    """

    # xxx.pdf => xxx.png
    png_file = f"{pdf_file[0:-4]}.png"

    if os.path.exists(png_file):
        return png_file

    cmd = f"soffice --headless --convert-to png {pdf_file}"

    if cmd is None:
        return None

    process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    process.wait()

    # returncode 不为 0 表示非正常退出
    if process.returncode and process.stdout:
        logger.warning(
            f"pdf:【{pdf_file}{cmd} 转换wmf文件失败: {process.stdout.read() !r}"
        )
        return None

    return png_file

结果如下:

截图 2024-01-10 09-36-24.png

转换为图片的第一页幻灯片如下:

Year-6-Ratio-Lesson-6_1.png

最后

当前这些函数都是分开定义的,也就是实际上可以根据需求和目的,自由的组合这些函数的调用。

小提示: 如果使用soffice转换一个多页的pdf文件为图片,默认只会转第一页幻灯片为图片。

好了,如果还有其他问题,欢迎留言进行讨论。