我正在使用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是否实现了类似的解决方案。
有什么想法吗?谢谢!
答案 0 :(得分:3)
仅供参考,有一种方法可以使用“差异样式”来实现。 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)
答案 1 :(得分: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"
修改:我已经将我的解决方案倾斜并将其解压缩为一个宝石https://github.com/sakovias/axlsx_styler