使用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
相关产品推荐
相关产品推荐

