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

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

通过 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 文件处理 云存储 开发

推荐文章

Vue3中如何处理异步操作?
2024-11-19 04:06:07 +0800 CST
介绍Vue3的静态提升是什么?
2024-11-18 10:25:10 +0800 CST
JavaScript 异步编程入门
2024-11-19 07:07:43 +0800 CST
thinkphp分页扩展
2024-11-18 10:18:09 +0800 CST
PHP如何进行MySQL数据备份?
2024-11-18 20:40:25 +0800 CST
一些实用的前端开发工具网站
2024-11-18 14:30:55 +0800 CST
MySQL死锁 - 更新插入导致死锁
2024-11-19 05:53:50 +0800 CST
WebSQL数据库:HTML5的非标准伴侣
2024-11-18 22:44:20 +0800 CST
Vue3中如何实现国际化(i18n)?
2024-11-19 06:35:21 +0800 CST
html文本加载动画
2024-11-19 06:24:21 +0800 CST
JavaScript设计模式:装饰器模式
2024-11-19 06:05:51 +0800 CST
程序员茄子在线接单