【问题标题】:Applying several styles to a cell in Excel spreadsheet with AXLSX gem使用 AXLSX gem 将多种样式应用于 Excel 电子表格中的单元格
【发布时间】:2014-11-14 15:18:46
【问题描述】:

我正在使用 AXLSX Ruby gem 生成 Excel 报告,但在以模块化方式将多种样式应用于单元格时遇到问题。

这是一个只有两种样式(“背景”和“背景粗体”)的示例,

require 'axlsx'

axlsx = Axlsx::Package.new
workbook = axlsx.workbook

with_background = workbook.styles.add_style bg_color: "E2D3EB"
bold_with_background = workbook.styles.add_style bg_color: "E2D3EB", b: true

workbook.add_worksheet do |sheet|
  sheet.add_row
  sheet.add_row ["", "Product", "Category", "Price"], style: [0, bold_with_background, bold_with_background, bold_with_background]
  sheet.add_row ["", "Butter", "Dairy", 4.99], style: [0, with_background, with_background, with_background]
  sheet.add_row ["", "Bread", "Baked Goods", 3.45], style: [0, with_background, with_background, with_background]
  sheet.add_row ["", "Broccoli", "Produce", 2.99], style: [0, with_background, with_background, with_background]
end

axlsx.serialize "grocery.xlsx"

结果如下,

现在,假设我必须在此表周围应用边框。如果我理解正确的话,我必须有很多样式才能到达那里:“左上边缘在背景上加粗”,“上边缘在背景上加粗”,“右上边缘在背景上加粗”,“在右边缘的背景上”等。

有没有一种方法可以将多个样式应用于单元格,而不必为每个可能的基本样式组合声明一个样式?

我想要类似的东西

sheet["B2"].add_style(bold).add_style(background).add_style(top_left_edge)

但不确定 gem 是否实现了类似的解决方案。

有什么想法吗?谢谢!

【问题讨论】:

    标签: ruby excel axlsx


    【解决方案1】:

    仅供参考,有一种方法可以使用“不同样式”来做到这一点。 Look at the docs on styles.rb

    基本上你声明你的风格类型是:dxf。默认值为:xf。其他一切都是一样的。从上面的链接(标题、货币和百分比是前面定义的正常样式):

    p = Axlsx::Package.new
    wb = p.workbook
    ws = wb.add_worksheet
    
    # define your styles
    profitable = wb.styles.add_style(:bg_color => "FFFF0000",
                               :fg_color=>"#FF000000",
                               :type => :dxf)
    
    ws.add_row ["Genreated At:", Time.now], :styles=>[nil, date_time]
    ws.add_row ["Previous Year Quarterly Profits (JPY)"], :style=>title
    ws.add_row ["Quarter", "Profit", "% of Total"], :style=>title
    ws.add_row ["Q1", 4000, 40], :style=>[title, currency, percent]
    ws.add_row ["Q2", 3000, 30], :style=>[title, currency, percent]
    ws.add_row ["Q3", 1000, 10], :style=>[title, currency, percent]
    ws.add_row ["Q4", 2000, 20], :style=>[title, currency, percent]
    
    ws.add_conditional_formatting("A1:A7", { :type => :cellIs, :operator => :greaterThan, :formula => "2000", :dxfId => profitable, :priority => 1 })
    f = File.open('example_differential_styling', 'w')
    p.serialize(f)
    

    【讨论】:

    • 谢谢@noel!看起来这就是我要找的东西。我将深入研究 gem 的代码。我想我应该在某个时候向 gem 添加一个示例,因为此功能非常有价值。
    【解决方案2】:

    我已经设法通过猴子修补Axlsx 类来覆盖单元格样式。这个想法是首先以 Ruby 哈希的形式将原始样式应用于单元格。完成后,可以为工作簿生成Axlsx 样式并应用它们。我现在可以将标记与样式分开,将样式应用为

    sheet["B2:D2"].add_style(b: true)
    sheet["B2:D5"].add_style(bg_color: "E2D3EB")
    workbook.apply_styles
    

    以下是我的 hacky 解决方案的完整列表。这不包括识别应该在专业代码中完成的其他事情中的独特样式。期待任何反馈。

    require 'axlsx'
    
    class Array
      def add_style(style)
        return unless map{ |e| e.kind_of? Axlsx::Cell }.uniq.first
        each { |cell| cell.add_style(style) }
      end
    end
    
    class Axlsx::Workbook
      attr_accessor :styled_cells
    
      def add_styled_cell(cell)
        self.styled_cells ||= []
        self.styled_cells << cell
      end
    
      def apply_styles
        return unless styled_cells
        styled_cells.each do |cell|
          cell.style = styles.add_style(cell.raw_style)
        end
      end
    end
    
    class Axlsx::Cell
      attr_accessor :raw_style
    
      def workbook
        row.worksheet.workbook
      end
    
      def add_style(style)
        self.raw_style ||= {}
        self.raw_style = raw_style.merge(style)
        workbook.add_styled_cell(self)
      end
    end
    
    axlsx = Axlsx::Package.new
    workbook = axlsx.workbook
    
    workbook.add_worksheet do |sheet|
      sheet.add_row
      sheet.add_row ["", "Product", "Category", "Price"]
      sheet.add_row ["", "Butter", "Dairy", 4.99]
      sheet.add_row ["", "Bread", "Baked Goods", 3.45]
      sheet.add_row ["", "Broccoli", "Produce", 2.99]
    
      sheet["B2:D2"].add_style(b: true)
      sheet["B2:D5"].add_style(bg_color: "E2D3EB")
    end
    
    workbook.apply_styles
    
    axlsx.serialize "grocery.xlsx"
    

    编辑:我已经整理好我的解决方案并将其提取到一个 gem https://github.com/sakovias/axlsx_styler

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多