使用powerpoint gem生成PPT时调用send_data导出文件损坏/无效如何解决
问题根因
- 第一种方案错误点:
- 读二进制PPTX文件时用了文本模式
'r',读取过程中会自动转换换行符,导致文件体积变大、内容损坏,必须用二进制读模式'rb' - MIME类型配置错误:
application/vnd.ms-powerpoint是.ppt格式的MIME,.pptx的正确MIME为application/vnd.openxmlformats-officedocument.presentationml.presentation - 变量名不一致:代码中定义的文件名为
pptname,但send_data中传的filename变量未赋值,也会导致下载异常
- 读二进制PPTX文件时用了文本模式
- 第二种方案错误点:
@deck是Powerpoint::Presentation类的实例对象,直接传入send_data会自动调用对象的to_s方法,输出的是对象的序列化字符串,而非PPT二进制内容,自然无法生成正常文件。
正确实现方案
方案1:修正本地临时文件读取逻辑(最稳妥)
修改文件打开模式、MIME类型和变量名即可,代码如下:
file_path = Rails.root.join('tmp', pptname) # 用二进制模式rb读取文件 File.open(file_path, 'rb') do |f| send_data f.read, filename: pptname, type: "application/vnd.openxmlformats-officedocument.presentationml.presentation", disposition: "attachment" end # 发送完成后可直接删除临时文件,避免磁盘占用 File.delete(file_path)
方案2:避免写本地临时文件(性能优化可选)
如果不想在本地留存临时文件,可以直接调用gem内部生成二进制内容的方法,无需先存到磁盘再读取:
# 跳过@deck.save步骤,直接获取二进制内容 ppt_binary = @deck.generate # 部分gem版本对应方法为.to_blob,可参考gem源码中save方法的内部实现调整 send_data ppt_binary, filename: pptname, type: "application/vnd.openxmlformats-officedocument.presentationml.presentation", disposition: "attachment"
内容的提问来源于stack exchange,提问作者elcodergrande
相关产品推荐
相关产品推荐

