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

使用combine_pdf gem合并S3桶中PDF文件时加载URL报错的解决方法

解决CombinePDF加载S3远程PDF URL报错的问题

嘿,我明白你碰到的麻烦了——CombinePDF的load方法默认是用来读取本地文件路径的,直接传S3的HTTPS URL肯定会抛出"No such file or directory"错误,因为它不会主动发起HTTP请求去下载远程文件。咱们得换个思路,先把S3上的PDF下载到本地临时文件,再用CombinePDF加载它。

方案1:如果用的是Rails Active Storage(推荐)

从代码里的@task&.assignable&.pdf_file来看,你大概率用了Rails的Active Storage来管理S3文件,这种情况直接用Active Storage的download方法最方便,还能避免预签名URL过期的问题:

require 'tempfile'

# 创建临时文件存储下载的PDF
temp_file = Tempfile.new(['s3_pdf', '.pdf'])
begin
  temp_file.binmode # 确保以二进制模式写入
  # 直接从Active Storage下载文件内容到临时文件
  temp_file.write(@task.assignable.pdf_file.download)
  temp_file.rewind # 把文件指针移到开头,方便后续读取

  # 现在可以正常加载临时文件了
  s3_pdf = CombinePDF.load(temp_file.path)
  pdf << s3_pdf
ensure
  # 用完一定要清理临时文件,避免占用磁盘空间
  temp_file.close
  temp_file.unlink
end

方案2:用open-uri直接下载远程URL

如果没用到Active Storage,或者需要直接用S3的URL,那可以用Ruby内置的open-uri库来下载文件到临时文件:

require 'open-uri'
require 'tempfile'

temp_file = Tempfile.new(['s3_pdf', '.pdf'])
begin
  # 发起HTTP请求下载远程PDF
  URI.open(@task.assignable.pdf_file.file.url) do |remote_file|
    temp_file.binmode
    temp_file.write(remote_file.read)
    temp_file.rewind
  end

  # 加载临时文件并合并
  s3_pdf = CombinePDF.load(temp_file.path)
  pdf << s3_pdf
ensure
  temp_file.close
  temp_file.unlink
end

为什么原来的代码不行?

CombinePDF.load的参数支持本地文件路径、File对象或者PDF二进制数据,但不支持直接传入远程HTTPS URL。它会把你传的URL当作本地文件路径去查找,自然找不到对应的文件,所以才会报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:23:46