继 http://ruby-china.org/topics/17978 帖子后,由于昨天开始在写一个 excel 打印的东西,感觉和楼主遇到了相同的问题。
功能分析:
目前我使用的是 axlsx 这个 gem. 目前没有任何结构的代码
module Printer
COLUMN_NAMES = {
:image => _("Image"),
:brand_name => _("Manufacturer Name"),
:name => _('Product Name'),
:dimension => _("Dimensions"),
:csi_category_code => _('CSI Category'),
:vendor => _('Vendor Info'),
:remark => _('notes'),
:updated_at => _('Last Updated'),
:symbol => _('Symbol'),
:description => _('Description'),
:area => _('Space'),
:application => _('Application'),
:manufacturer_website => _('Manufacturer Website'),
:made_in => _('Made In'),
:other_brand => _('Acceptable Brands'),
:lbc_material_title => _("LBC Material Title"),
:lbc_status => _("LBC Status"),
:team_member => _("Team Member"),
:zone => _("Zone"),
:zone_radius => _("Radius (km)"),
:sourcing_row_material => _("Sourcing Raw Materials (km)"),
:red_list_free => _("Red List Free? (y/n)"),
:product_content => _("Primary Contents"),
:product_location => _("Product Location"),
:product_distance => _("Distance from MNFR (km)"),
:product_responsible_industry => _("Responsible Industry"),
:product_appiled => _("Exception Applied (y/n)"),
:manufacturer_location => _("manufacturer Location"),
:manufacturer_distance => _("Distance from Site (km)"),
:red_list => _("Red List (y/n)"),
:app_sourcing => _("App. Sourcing (y/n)"),
:fsc_certified => _("FSC Certified (y/n)"),
:lbc_notes => _("LBC Notes"),
:floor_area => _("Floor Area (m^2)"),
:height => _("Height (m)"),
:floor_area => _("Space Volume (m^3)"),
:iaq_certification => _("IAQ Certification"),
:conversion_factor => _("Conversion Factor"),
:test_result => _("Test Result / Limit Value (µg/m^3)"),
:iaq_notes => _("IAQ Notes"),
:material_quantity => _("Material Quantity"),
:formaldehyde => _("Formaldehyde (µg/m^3)"),
:formaldehyde_projected_emission => _("Formaldehyde Projected Emissions (µg/m^3)"),
:tvoc => _("TVOC (µg/m^3)"),
:tvoc_projected_emission => _("TVOC Projected Emissions (µg/m^3)")
}
XLSX_STYLES = {
:title => {
:bg_color => "ff",
:fg_color => "00",
:sz => 14, :b => true,
:border => { :style => :thin, :color => "00" },
:alignment => { :horizontal=> :center, :vertical => :center }
},
:header => {
:bg_color => "ff",
:fg_color => "00",
:sz => 14,
:b => true,
:border => { :style => :thin, :color => "00" },
:alignment => { :horizontal=> :center, :vertical => :center }
},
:center => {
:alignment => {
:horizontal=> :center,
:vertical => :center
}
}
}
CATEGORT_COLUMNS = {
:basic => %w(image brand_name name dimension csi_category_code vendor remark updated_at),
:schedule => %w(symbol description area application image ,
:lbc => %w(csi_category_code lbc_material_title lbc_status team_member zone),
:voc => %w(area floor_area height floor_area csi_category_code brand_name )
}
def self.print!(records, options={})
p = Axlsx::Package.new
p.use_shared_strings = true
wb = p.workbook
wb.styles do |s|
title_style = s.add_style XLSX_STYLES[:title]
header_style = s.add_style XLSX_STYLES[:header]
center_cell = s.add_style XLSX_STYLES[:center]
sheet = wb.add_worksheet
#render title
# title = Axlsx::RichText.new
# title.add_run("#{options[:workspace]}\n", :b => true)
# title.add_run("#{_('Project:')} #{options[:project]}\n", :b => true)
# title.add_run("#{_('Date:')} #{Time.now.to_s(:db)}", :b => true)
# sheet.add_row [title], :height => 40, :style => Array.new( 1, title_style)
# #sheet.merge_cells("A1:G1")
#render header
mode = (options[:mode] || options['mode']).to_sym
mode = :basic unless CATEGORT_COLUMNS.has_key? mode
columns = CATEGORT_COLUMNS[mode]
headers = columns.map{|key| COLUMN_NAMES[key.to_sym]}
sheet.add_row headers, :height => 30, :style => Array.new( headers.size, header_style)
#render records content.
#self.send("print_#{mode}", records, sheet, s)
records.each_with_index do |material, index|
values = material.attributes.values_at(*columns)
#render image
if columns.index('image') && material.image
_index = columns.index('image')
values[_index] = ''
img = "#{Rails.root}/public#{material.image.file.url.gsub(/\?\d+$/,"")}"
sheet.add_image(:image_src => img, :noSelect => false, :noMove => false) do |image|
image.width = 100
image.height = 100
image.start_at _index, index+1
end
end
#render vendor info
if columns.index('vendor') && material.vendor
_index = columns.index('vendor')
values[_index] = values[_index].values.join("\n")
end
# format updated_at
if columns.index('updated_at')
_index = columns.index('updated_at')
values[_index] = values[_index].localtime.to_s(:db)
end
sheet.add_row values, :height => 78, :style => Array.new(columns.size, center_cell)
end
end
p.to_stream.read
end
end
目前感觉这代码就不够稳健,无法高度适应 excel 打印样式的自定义,需要重构,我看到上个帖子有兄台提到了模版模式,我也准备采用,带式打印的基本模版,我发现我还没理清。
对代码结构涉及能力不是很强,希望大家能给点意见和建议。。谢谢。