Rails Rails 有哪些导出 Excel 的好方法呢?

LPFpengfei · 2018年10月31日 · 最后由 adamshen 回复于 2018年10月31日 · 3892 次阅读

写在前面

我是一个新手程序员,接触最多的就是导出数据,在上一个项目中,我们使用的是 excel 导出的 Gem,axlsx_rails https://github.com/straydogstudio/axlsx_rails; 在现在的项目中,我们用的是 spreadsheet。

现在,我们的重构项目中,我不想再使用这两种导出的方式,因为两种方式都不能满足我的个性化定制的导出,每次各种人过来问我要各种样式的数据导出。 每次我都需要写一堆脚本去做导出。

期望大家给我一些指点,有没有一种导出的 gem 可以支持各种样式,各种定制化的字段导出的?

axlsx_rails

使用这个 gem 导出代码时,需要在 controller 中定义导出的 action

class ButtonController < ApplicationController
  def action_name
    @buttons = Button.all
    respond_to do |format|
      format.xlsx
    end
  end
end

然后 view 层,需要在定义一个 excel.xlsx.axlsx 的文件 你可以在每个导出的文件时定义样式,字体等等

wb = xlsx_package.workbook
wb.add_worksheet(name: "后台批量导入客户列表") do |sheet|
  sheet.add_row ["后台批量导入客户列表"]
  sheet.add_row ["手机号", "姓名", "性别", "身份证号", "出生日期", "邮箱", "联系地址", "邮政编码", "学历", "备注信息", "是否已存在", "导入状态", "创建时间"]
    @batch_customers.find_each do |batch_customer|
    sheet.add_row [batch_customer.phone, batch_customer.name, batch_customer.gender, batch_customer.id_no, batch_customer.birthday, batch_customer.email, batch_customer.address, batch_customer.postcode, batch_customer.education, batch_customer.remark, batch_customer.is_exists == 1 ? '已存在' : '不存在', get_batch_customer_status(batch_customer.status), batch_customer.try(:batch_customer_info).try(:name), batch_customer.created_at.strftime('%Y-%m-%d %H:%M:%S')], :type => :string
  end
end

但是这种方式对于自定义的导出非常的不友好。

spreadsheet

这个 gem 可以定义新的 Excel 或者读取一个 Excel 中的数据,是一个很好的导出导入 Excel 的 gem。

在使用这个 gem 中,你可以自定义导出的通用样式

module ExcelExportService
      def export_excel file_name, hash_data, header
      folder = Rails.root.join('public', "excels")
      FileUtils.mkdir_p folder if !folder.exist?
      header_format = Spreadsheet::Format.new(
          :weight => :bold,
          :horizontal_align => :left,
          :bottom => :medium,
          :locked => false,
          text_justlast: true,
          vertical_align: :center
        )
      default_format = Spreadsheet::Format.new(:horizontal_align => :left, locked: false, text_justlast: true,vertical_align: :center)
      book = Spreadsheet::Workbook.new
      hash_data.each do |key, data|
        sheet = book.create_worksheet name: key.to_s
        sheet.default_format = default_format
        sheet.row(0).default_format = header_format
        header.each do |col|
          sheet.row(0).push col
        end
        data.each_with_index do |line, line_no|
          line_no += 1
          line.each do |col|
            col ||= ""
            sheet.row(line_no).push col
          end
        end
      end
      book.write File.join(folder, "#{file_name}.xls")
      "/excels/#{file_name}.xls"
    end
end

然后我们可以在项目中,任意的地方调用这个方法导出 Excel

def export_botao starting_time, ending_time
  data = Order.where(created_at: starting_time..ending_time).order("botao_orders.created_at").map do |order|
    [order&.base_order&.no,order.order_number,order.botao_order_number,order.organization&.name, order.user&.name,order.check_in_time.strftime("%F %T"),
      order.check_out_time.strftime("%F %T"),order.people_num,order.room_unm,order.total_price&.to_money,order.state, order.memo, order.admin&.name,
      order.created_at.strftime("%F %T")
    ]
  end
  excel_data = {'订单信息': data}
  ExcelExportService::export_excel('数据导出',excel_data,['订单号','铂涛订单号','外部订单号','企业名','用户名','入住时间','离店时间','人数','房间数','总价格','状态','备注','操作人','创建时间'])
end

写在最后

我也在试着换一种导出的方式,大家还有其他的导出方式吗?

谢谢

https://github.com/randym/axlsx 这个应该也是可以自定义样式之类的

可以试试这个,帮你封装了一些很便捷的方法,省去不少事。

https://github.com/westonganger/spreadsheet_architect

LPFpengfei 关闭了讨论。 01月29日 16:38
需要 登录 后方可回复, 如果你还没有账号请 注册新账号