module Aio::Base::Toolkit module ExcelWps class WorkBook include Aio::Ui::Verbose @@worksheets_name = [] def initialize(encoding = "utf-8") if Aio::Base::Toolkit::OS.windows? require "win32ole" else print_error "只有Windows系统才能使用Excel模块" exit 0 end @excel = WIN32OLE.new("excel.Application") @excel.visible = false @workbook = @excel.workbooks.add @encoding = encoding create_style end # 警告提示开关 def display_alerts=(bool) @excel.DisplayAlerts = bool end def add_worksheet(name) while @@worksheets_name.include?(name) name += "1" end @@worksheets_name << name worksheet = @workbook.worksheets.add worksheet.activate worksheet.name = name return WorkSheet.new(worksheet) end def create_style sty = @workbook.styles.add("NormalStyle") self.class.normal_style(sty) sty = @workbook.styles.add("BoldStyle") self.class.bold_style(sty) sty = @workbook.styles.add("TitleStyle") self.class.title_style(sty) end def self.normal_style(sty) sty.font.size = 9 sty.borders(7).linestyle = 1 sty.borders(8).linestyle = 1 sty.borders(9).linestyle = 1 sty.borders(10).linestyle = 1 sty.HorizontalAlignment = -4108 end def self.bold_style(sty) sty.font.size = 9 sty.font.bold = true sty.borders(7).linestyle = 1 sty.borders(8).linestyle = 1 sty.borders(9).linestyle = 1 sty.borders(10).linestyle = 1 sty.HorizontalAlignment = -4108 end def self.title_style(sty) sty.font.size = 20 sty.font.bold = true sty.borders(7).linestyle = 1 sty.borders(8).linestyle = 1 sty.borders(9).linestyle = 1 sty.borders(10).linestyle = 1 sty.HorizontalAlignment = -4108 end def show @excel.visible = true end def save(path) @workbook.saveas(path) end def close @workbook.close @excel.quit end end # class WorkBook class WorkSheet IMAGE_ROW_NUM = 56 @@worksheets_name = [] def initialize(worksheet) @row_count = 1 @worksheet = worksheet @nil_space = [] end # 增加一个空行 def add_space_line(n=1) return if n < 1 @row_count += n end # 对列进行合并 def merge(range1, range2) @worksheet.range("#{range1}:#{range2}").merge end # 添加标题行 def add_title(name) add_row.add_cell(name, false, "BoldStyle") end # 设置列的宽度 def width(col, width) @worksheet.Columns("#{col}:#{col}").ColumnWidth = width end def height(height) @row_height = height end # 增加Row类 def add_row(&block) @current_row = Row.new(@worksheet, @row_count) @current_row.height = @row_height if @row_height @row_count += 1 yield @current_row if block return @current_row end # 返回此时的Row类 def current_row return @current_row end # 返回此时的行索引 def current_row_id return @current_row.row_id end # 添加图像 def add_image(image_path) return unless File.exist?(image_path) add_space_line add_row cell_name = current_row.first_cell @worksheet.Range(cell_name).Select @worksheet.Pictures.Insert(image_path) add_space_line IMAGE_ROW_NUM end # 判断是否有垂直分页符存在 def has_pagebreak? @worksheet.VPageBreaks.count > 0 end # 对列修改分页符 def pagebreak(col) @worksheet.VPageBreaks(1).Location = @worksheet.columns(col) end # 返回::WorkSheet def worksheet @worksheet end end class Row FILL_TYPE = 4 attr_reader :row_id @@cell_map = ("A".."Z").to_a def initialize(worksheet, row_id) @row_id = row_id @cell_count = 0 @worksheet = worksheet @nil_space = [] end # 此时的单元格 def curent_cell return cell_name(@cell_count) end # 第一个单元格 def first_cell return cell_name(0) end # 设置行高 def height=(height) @worksheet.rows(@row_id).RowHeight = height end # 增加单元格 def add_cell(value, auto_fit = false, style = "NormalStyle") range = @worksheet.Range(cell_name(@cell_count)) range.Value = value.to_s range.Style = style range.Columns.AutoFit if auto_fit @cell_count += 1 while(@nil_space.include?(to_letter(@cell_count))) do range = @worksheet.Range(cell_name(@cell_count)) range.Value = "" range.Style = style @cell_count += 1 end end # 通过索引变成对应的字母 def to_letter(index) @@cell_map.at(index) end # 特别注意,由于Toolkit中加入了Array,String的模块 # 所以判断的时候特别注意要是 def << (arr) case arr when ::Array arr.size.times do |t| add_cell(arr[t]) end when ::String add_cell(arr) end end # 获得单元格的名字(通过索引) def cell_name(index) second = index % 26 first = (index - second) / 26 if first == 0 return @@cell_map[second] + @row_id.to_s end first -= 1 return @@cell_map[first] + @@cell_map[second] + @row_id.to_s end # 获得单元格的名字(通过字母) def cell_name!(letter) return letter + @row_id.to_s end def set_cell(index, value, auto_fit = false, style = "NormalStyle") range = @worksheet.Range(cell_name(index)) range.Value = value.to_s range.Style = style range.Columns.AutoFit if auto_fit end # 设置单元格风格 def set_style(letter, style = "NormalStyle") range = @worksheet.range(cell_name!(letter)) range.Style = style end # 合并一行中的单元格 def merge(idx_begin, idx_end) cell_begin = "#{idx_begin}#{@row_id}" cell_end = "#{idx_end}#{@row_id}" range = @worksheet.Range("#{cell_begin}:#{cell_end}") range.merge tmp = ((idx_begin.upcase)..(idx_end.upcase)).to_a tmp.shift @nil_space = (@nil_space | tmp).sort end # 开启自动换行 def wraptext(letter) range = @worksheet.range(cell_name!(letter)) range.WrapText = true end # 对此时的行的下方下分页符 def pagebreak @worksheet.rows(@row_id+1).PageBreak = 1 end # 返回此时的::Row类 def real_row @worksheet.rows(@row_id) end alias :style :set_style end end end