代码 api远程把word文件转换为pdf

2024-11-19 03:48:33 +0800 CST views 503

通过 API 接收一个远程文件 URL,然后服务器从该 URL 下载文件,再将其转换为 PDF,并将前两页转换为图片,最终上传到 阿里云 OSS。这里不再是通过文件上传的方式,而是通过提交远程 URL 地址。

调整后的解决方案

我们将修改之前的 Flask API,让它接受 远程文件 URL 作为输入。

依赖库安装

首先,确保安装以下所需的依赖:

pip install flask requests pdf2image oss2 python-docx
sudo yum install libreoffice poppler-utils

完整示例代码

from flask import Flask, request, jsonify
import os
import shutil
import requests
import subprocess
from pdf2image import convert_from_path
import oss2

# Flask 应用实例
app = Flask(__name__)
UPLOAD_FOLDER = '/tmp'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# 阿里云 OSS 配置
ACCESS_KEY_ID = 'your_access_key_id'
ACCESS_KEY_SECRET = 'your_access_key_secret'
BUCKET_NAME = 'your_bucket_name'
ENDPOINT = 'your_endpoint'
bucket = oss2.Bucket(oss2.Auth(ACCESS_KEY_ID, ACCESS_KEY_SECRET), ENDPOINT, BUCKET_NAME)

# 允许上传的文件扩展名
ALLOWED_EXTENSIONS = {'pdf', 'docx', 'txt', 'pptx'}

def allowed_file(filename):
    """检查文件是否是允许的格式"""
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def download_file(url):
    """从远程 URL 下载文件"""
    local_filename = os.path.join(UPLOAD_FOLDER, url.split("/")[-1])
    response = requests.get(url, stream=True)
    if response.status_code == 200:
        with open(local_filename, 'wb') as f:
            f.write(response.content)
        return local_filename
    return None

def convert_to_pdf(input_file):
    """使用 LibreOffice 将文件转换为 PDF"""
    output_file = os.path.splitext(input_file)[0] + '.pdf'
    command = f'libreoffice --headless --convert-to pdf "{input_file}" --outdir {UPLOAD_FOLDER}'
    subprocess.run(command, shell=True)
    pdf_file = os.path.join(UPLOAD_FOLDER, os.path.basename(output_file))
    if os.path.exists(pdf_file):
        return pdf_file
    return None

def pdf_to_images(pdf_path):
    """将 PDF 前两页转换为图片"""
    images = convert_from_path(pdf_path, first_page=1, last_page=2)
    image_paths = []
    for i, image in enumerate(images):
        image_path = os.path.join(UPLOAD_FOLDER, f'page_{i + 1}.png')
        image.save(image_path, 'PNG')
        image_paths.append(image_path)
    return image_paths

def upload_to_oss(file_path):
    """上传文件到阿里云 OSS"""
    filename = os.path.basename(file_path)
    oss_path = f'uploads/{filename}'
    bucket.put_object_from_file(oss_path, file_path)
    return f'https://{BUCKET_NAME}.{ENDPOINT}/{oss_path}'

def cleanup_temp_files(*file_paths):
    """删除临时文件"""
    for file_path in file_paths:
        if os.path.exists(file_path):
            os.remove(file_path)

@app.route('/upload', methods=['POST'])
def upload_file():
    """处理上传 URL 请求"""
    file_url = request.form.get('url')
    if not file_url:
        return jsonify({'code': 1, 'message': '未提供 URL'}), 400

    # 从 URL 下载文件
    local_file = download_file(file_url)
    if not local_file or not allowed_file(local_file):
        return jsonify({'code': 1, 'message': '文件下载失败或文件类型不支持'}), 400

    try:
        # 1. 判断文件类型并转换为 PDF
        if local_file.endswith('.pdf'):
            pdf_file = local_file
        else:
            pdf_file = convert_to_pdf(local_file)
            if not pdf_file:
                return jsonify({'code': 1, 'message': '文件转换为 PDF 失败'}), 500

        # 2. 转换 PDF 前两页为图片
        image_paths = pdf_to_images(pdf_file)

        # 3. 上传 PDF 和图片到 OSS
        pdf_url = upload_to_oss(pdf_file)
        image_urls = [upload_to_oss(img) for img in image_paths]

        # 4. 返回结果
        return jsonify({
            'code': 0,
            'data': {
                'pdfurl': pdf_url,
                'views': image_urls
            }
        })
    finally:
        # 5. 清理临时文件
        cleanup_temp_files(local_file, pdf_file, *image_paths)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

代码说明

  1. Flask 接口

    • POST /upload:接收一个包含远程 URL 的请求。
    • 检查文件是否可以从 URL 下载并保存到本地。
  2. 文件下载与处理

    • 从 URL 下载文件到服务器。
    • 如果文件是非 PDF 格式,则使用 LibreOffice 将其转换为 PDF。
    • 使用 pdf2image 将 PDF 的前两页转换为 PNG 图片。
  3. 阿里云 OSS 上传

    • 上传 PDF 和图片到 OSS,并返回 URL。
  4. 清理临时文件

    • 上传完成后,自动删除服务器上的临时文件。

使用示例

使用 curl 命令进行测试:

curl --request POST \
  --url http://localhost:5000/upload \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data 'url=http://qiye.dev.udwz.cn/123.docx'

示例响应

{
  "code": 0,
  "data": {
    "pdfurl": "https://your_bucket.your_endpoint/uploads/123.pdf",
    "views": [
      "https://your_bucket.your_endpoint/uploads/page_1.png",
      "https://your_bucket.your_endpoint/uploads/page_2.png"
    ]
  }
}

注意事项

  • 确保替换阿里云 OSS 的配置信息(ACCESS_KEY_ID, ACCESS_KEY_SECRET, BUCKET_NAME, ENDPOINT)。
  • 确保 LibreOfficepoppler-utils 已正确安装,以支持文档转换。
  • 请确保服务器 /tmp 目录有写入权限。
{"code":0,"data":{"pdfurl":"https://orangerescue2022.oss-cn-hangzhou.aliyuncs.com/pdf/123-d60becd4-1de5-4ed0-9ec3-0b3972b781f2.pdf","views":["https://orangerescue2022.oss-cn-hangzhou.aliyuncs.com/pdf/9f09ceb9-8ff0-4ad2-9030-771dc0cd86fc.png","https://orangerescue2022.oss-cn-hangzhou.aliyuncs.com/pdf/a7cb30b9-fe72-4e44-949d-f6a7b5352052.png"]}}

复制全文 生成海报 API 文件处理 云存储 开发

推荐文章

Elasticsearch 监控和警报
2024-11-19 10:02:29 +0800 CST
windows安装sphinx3.0.3(中文检索)
2024-11-17 05:23:31 +0800 CST
如何在 Linux 系统上安装字体
2025-02-27 09:23:03 +0800 CST
Redis和Memcached有什么区别?
2024-11-18 17:57:13 +0800 CST
使用Vue 3和Axios进行API数据交互
2024-11-18 22:31:21 +0800 CST
全栈工程师的技术栈
2024-11-19 10:13:20 +0800 CST
CSS 奇技淫巧
2024-11-19 08:34:21 +0800 CST
html流光登陆页面
2024-11-18 15:36:18 +0800 CST
Elasticsearch 的索引操作
2024-11-19 03:41:41 +0800 CST
Golang Sync.Once 使用与原理
2024-11-17 03:53:42 +0800 CST
支付轮询打赏系统介绍
2024-11-18 16:40:31 +0800 CST
HTML和CSS创建的弹性菜单
2024-11-19 10:09:04 +0800 CST
markdown语法
2024-11-18 18:38:43 +0800 CST
2025年,小程序开发到底多少钱?
2025-01-20 10:59:05 +0800 CST
Vue 3 中的 Watch 实现及最佳实践
2024-11-18 22:18:40 +0800 CST
程序员茄子在线接单