ruby-on-rails - Ruby on Rails 和 rubyzip:在 Windows 上损坏的 powerpoint 修改
问题描述
我正在使用 ruby on rails 根据我的 postgres 数据库中的数据修改 powerpoint 演示文稿现有模板的 xml 文件(打开 xml)。
我面临的问题是,在使用 windows 机器从 heroku 生成和下载文件后,microsoft powerpoint 检测到文件已损坏并尝试修复。修复PowerPoint中生成的文件后,文件可以正确打开。
如果我从 Linux 机器下载文件并将文件发送到 Windows 机器,文件会正确打开而不会发出警告或尝试修复。生成的 powerpoint 也可以在 Open office 上正确打开。
从技术上讲,这些是我用来生成文件的步骤。
- 从我的应用程序的资产文件夹中打开模板
- 使用 Rubyzip gem 提取 tmp 文件夹中的文件
- 使用 Nokogiri 打开和修改单个文件
- 将文件压缩为 .pptx 文件
- 使用活动存储上传/保存文件
将用户重定向到要下载的文件
提取文件方法
def self.extract_files(dir_prefix)
Zip::File.open(Rails.root.join('app', "assets", "ppt", 'test_8.pptx')) do |z| z.each do |f| ##Extract files in a directory f_path=File.join("tmp/#{dir_prefix}_destination", f.name) FileUtils.mkdir_p(File.dirname(f_path)) z.extract(f, f_path) unless File.exist?(f_path) end end
结尾
使用以下命令打开文件进行操作:
chartxml = File.open(Rails.root.join('tmp', tmp_extract_folder, 'ppt', 'charts', 'chart5.xml'))
##Manipulation logic here
File.write(Rails.root.join('tmp', tmp_extract_folder, 'ppt', 'charts', 'chart5.xml'), doc.to_xml)
使用以下方法重新压缩文件:
zf =ZipFileGenerator.new("tmp/#{dir_prefix}_destination", "tmp/#{dir_prefix}_zipped.pptx")
zip 文件生成器的实现与 Rubyzip 的 github repo上提供的相同
然后我使用活动存储进行存储,使用:
ppt = Powerpoint.new(name: "#{dir_prefix}")
ppt.file.attach(
io: File.open("tmp/#{dir_prefix}_zipped.pptx"), filename: 'Synthese.pptx', content_type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
)
ppt.save
render :js => "window.location = '#{download_ppt_path(dir_prefix: dir_prefix)}'"
然后用户下载文件:
ppt = Powerpoint.where(name: dir_prefix)
redirect_to rails_blob_path(ppt.first.file, disposition: "attachment")
我尝试取消注释处理 xml 文件的代码,只是解压缩和重新压缩;我仍然面临同样的问题。
解决方案
推荐阅读
- javascript - 如何一键快速更改课程两次
- google-chrome - Chrome 开发工具无法打开。我该如何解决这个问题?
- php - 如何使用外观获取当前会话实例
- c - Libav(ffmpeg)容器编解码器时基和流时基的目的是什么?
- php - 类别和子类别的父 ID
- java - 在 Java 中的 JSON 文件中查找用户输入
- javascript - 如何清除处理文件下载且不导航的 HTML 表单
- java - Unknown mappedBy in:... 引用的属性未知
- laravel - Laravel 8 - 有条件地记住缓存中的值
- javascript - 为什么我的搜索功能不适用于 SpaceX api?