office_elin 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/excel_wps.rb ADDED
@@ -0,0 +1,433 @@
1
+ module ExcelWps
2
+ class WorkBook
3
+
4
+ @@worksheets_name = []
5
+ def initialize(encoding = "utf-8")
6
+
7
+ if OS.windows?
8
+ require "win32ole"
9
+ else
10
+ print "只有Windows系统才能使用Excel模块"
11
+ exit 0
12
+ end
13
+
14
+
15
+ @excel = WIN32OLE.new("excel.Application")
16
+ @excel.visible = false
17
+ @workbook = @excel.workbooks.add
18
+ @encoding = encoding
19
+ create_style
20
+ end
21
+
22
+ # 警告提示开关
23
+ def display_alerts=(bool)
24
+ @excel.DisplayAlerts = bool
25
+ end
26
+
27
+ def add_worksheet(name)
28
+ while @@worksheets_name.include?(name)
29
+ name += "1"
30
+ end
31
+ @@worksheets_name << name
32
+ worksheet = @workbook.worksheets.add
33
+ worksheet.activate
34
+
35
+ # 在同一进程中多次打开会出现name的问题, 所以干脆全部使用sheet
36
+ # worksheet.name = name
37
+ worksheet.name = "sheet"
38
+ return WorkSheet.new(worksheet)
39
+ end
40
+
41
+ def create_style
42
+ sty = @workbook.styles.add("NormalStyle")
43
+ self.class.normal_style(sty)
44
+
45
+ sty = @workbook.styles.add("BoldStyle")
46
+ self.class.bold_style(sty)
47
+
48
+ sty = @workbook.styles.add("TitleStyle")
49
+ self.class.title_style(sty)
50
+ end
51
+
52
+ def self.normal_style(sty)
53
+ sty.font.size = 9
54
+ sty.borders(7).linestyle = 1
55
+ sty.borders(8).linestyle = 1
56
+ sty.borders(9).linestyle = 1
57
+ sty.borders(10).linestyle = 1
58
+ sty.HorizontalAlignment = -4108
59
+ end
60
+
61
+ def self.bold_style(sty)
62
+ sty.font.size = 9
63
+ sty.font.bold = true
64
+ sty.borders(7).linestyle = 1
65
+ sty.borders(8).linestyle = 1
66
+ sty.borders(9).linestyle = 1
67
+ sty.borders(10).linestyle = 1
68
+ sty.HorizontalAlignment = -4108
69
+ end
70
+
71
+ def self.title_style(sty)
72
+ sty.font.size = 20
73
+ sty.font.bold = true
74
+ sty.borders(7).linestyle = 1
75
+ sty.borders(8).linestyle = 1
76
+ sty.borders(9).linestyle = 1
77
+ sty.borders(10).linestyle = 1
78
+ sty.HorizontalAlignment = -4108
79
+ end
80
+
81
+ def show
82
+ @excel.visible = true
83
+ end
84
+
85
+ def save(path)
86
+ @workbook.saveas(path)
87
+ end
88
+
89
+ def close
90
+ @workbook.close
91
+ @excel.quit
92
+ end
93
+ end # class WorkBook
94
+
95
+ class WorkSheet
96
+ IMAGE_ROW_NUM = 56
97
+ @@worksheets_name = []
98
+ def initialize(worksheet)
99
+ @row_count = 1
100
+ @worksheet = worksheet
101
+ @nil_space = []
102
+ end
103
+
104
+ # 增加一个空行
105
+ def add_space_line(n=1)
106
+ return if n < 1
107
+ @row_count += n
108
+ end
109
+
110
+ # 对列进行合并
111
+ def merge(range1, range2)
112
+ @worksheet.range("#{range1}:#{range2}").merge
113
+ end
114
+
115
+ # 产生 ::Range 类
116
+ def range(str)
117
+ @worksheet.range(str)
118
+ end
119
+
120
+ # 添加标题行
121
+ def add_title(name)
122
+ add_row.add_cell(name, false, "BoldStyle")
123
+ end
124
+
125
+ # 设置列的宽度
126
+ def width(col, width)
127
+ @worksheet.Columns("#{col}:#{col}").ColumnWidth = width
128
+ end
129
+
130
+ def height(height)
131
+ @row_height = height
132
+ end
133
+
134
+ # 增加Row类
135
+ def add_row(&block)
136
+ @current_row = Row.new(@worksheet, @row_count)
137
+ @current_row.height = @row_height if @row_height
138
+ @row_count += 1
139
+ yield @current_row if block
140
+ return @current_row
141
+ end
142
+
143
+ # 返回此时的Row类
144
+ def current_row
145
+ return @current_row
146
+ end
147
+
148
+ # 返回此时的行索引
149
+ def current_row_id
150
+ return @current_row.row_id
151
+ end
152
+
153
+ # 添加图像
154
+ def add_image(image_path)
155
+ return unless File.exist?(image_path)
156
+ add_space_line
157
+ add_row
158
+ cell_name = current_row.first_cell
159
+ @worksheet.Range(cell_name).Select
160
+ @worksheet.Pictures.Insert(image_path)
161
+ add_space_line IMAGE_ROW_NUM
162
+ end
163
+
164
+ # 判断是否有垂直分页符存在
165
+ def has_pagebreak?
166
+ @worksheet.VPageBreaks.count > 0
167
+ end
168
+
169
+ # 对列修改分页符
170
+ def pagebreak(col)
171
+ @worksheet.VPageBreaks(1).Location = @worksheet.columns(col)
172
+ end
173
+
174
+ # 返回::WorkSheet
175
+ def worksheet
176
+ @worksheet
177
+ end
178
+
179
+ # 添加图表
180
+ def add_chart(&block)
181
+ ch = @worksheet.Shapes.AddChart
182
+ active = ch.chart
183
+
184
+ # 占位符
185
+ block.call(Chart.new(active))
186
+
187
+ ch.copy
188
+ end
189
+ end # SheetWork Class
190
+
191
+ class Row
192
+ FILL_TYPE = 4
193
+
194
+ attr_reader :row_id
195
+
196
+ @@cell_map = ("A".."Z").to_a
197
+ def initialize(worksheet, row_id)
198
+ @row_id = row_id
199
+ @cell_count = 0
200
+ @worksheet = worksheet
201
+ @nil_space = []
202
+ end
203
+
204
+ # 此时的单元格
205
+ def curent_cell
206
+ return cell_name(@cell_count)
207
+ end
208
+
209
+ # 第一个单元格
210
+ def first_cell
211
+ return cell_name(0)
212
+ end
213
+
214
+ # 设置行高
215
+ def height=(height)
216
+ @worksheet.rows(@row_id).RowHeight = height
217
+ end
218
+
219
+ # 增加单元格
220
+ def add_cell(value, auto_fit = false, style = "NormalStyle")
221
+ range = @worksheet.Range(cell_name(@cell_count))
222
+ range.Value = value.to_s
223
+ range.Style = style
224
+ range.Columns.AutoFit if auto_fit
225
+ @cell_count += 1
226
+ while(@nil_space.include?(to_letter(@cell_count))) do
227
+ range = @worksheet.Range(cell_name(@cell_count))
228
+ range.Value = ""
229
+ range.Style = style
230
+ @cell_count += 1
231
+ end
232
+
233
+ end
234
+
235
+ # 通过索引变成对应的字母
236
+ def to_letter(index)
237
+ @@cell_map.at(index)
238
+ end
239
+
240
+ # 特别注意,由于Toolkit中加入了Array,String的模块
241
+ # 所以判断的时候特别注意要是
242
+ def << (arr)
243
+ case arr
244
+ when ::Array
245
+ arr.size.times do |t|
246
+ add_cell(arr[t])
247
+ end
248
+ when ::String
249
+ add_cell(arr)
250
+ end
251
+ end
252
+
253
+ # 获得单元格的名字(通过索引)
254
+ def cell_name(index)
255
+ second = index % 26
256
+ first = (index - second) / 26
257
+ if first == 0
258
+ return @@cell_map[second] + @row_id.to_s
259
+ end
260
+ first -= 1
261
+ return @@cell_map[first] + @@cell_map[second] + @row_id.to_s
262
+ end
263
+
264
+ # 获得单元格的名字(通过字母)
265
+ def cell_name!(letter)
266
+ return letter + @row_id.to_s
267
+ end
268
+
269
+ def set_cell(index, value, auto_fit = false, style = "NormalStyle")
270
+ range = @worksheet.Range(cell_name(index))
271
+ range.Value = value.to_s
272
+ range.Style = style
273
+ range.Columns.AutoFit if auto_fit
274
+ end
275
+
276
+ # 设置单元格风格
277
+ def set_style(letter, style = "NormalStyle")
278
+ range = @worksheet.range(cell_name!(letter))
279
+ range.Style = style
280
+ end
281
+
282
+ # 合并一行中的单元格
283
+ def merge(idx_begin, idx_end)
284
+ cell_begin = "#{idx_begin}#{@row_id}"
285
+ cell_end = "#{idx_end}#{@row_id}"
286
+ range = @worksheet.Range("#{cell_begin}:#{cell_end}")
287
+ range.merge
288
+ tmp = ((idx_begin.upcase)..(idx_end.upcase)).to_a
289
+ tmp.shift
290
+ @nil_space = (@nil_space | tmp).sort
291
+ end
292
+
293
+ # 开启自动换行
294
+ def wraptext(letter)
295
+ range = @worksheet.range(cell_name!(letter))
296
+ range.WrapText = true
297
+ end
298
+
299
+ # 对此时的行的下方下分页符
300
+ def pagebreak
301
+ @worksheet.rows(@row_id+1).PageBreak = 1
302
+ end
303
+
304
+ # 返回此时的::Row类
305
+ def real_row
306
+ @worksheet.rows(@row_id)
307
+ end
308
+
309
+ alias :style :set_style
310
+ end
311
+
312
+ # 图表
313
+ class Chart
314
+
315
+ # 图形类型
316
+ ColumnClustered = 51 # 簇状柱形图
317
+ ColumnStacked = 52 # 堆积柱状图
318
+ Doughnut = -4120 # 圆环图
319
+ Line = 4 # 折线图
320
+ Pie = 5 # 饼图
321
+ BarClustered = 57 # 簇状条形图
322
+
323
+ # 标签数据
324
+ DataLabelsShowLabel = 4 # 数据点所属的分类
325
+ DataLabelsShowLabelAndPercent = 5 # 占比百分比以及所属分类,仅饼图
326
+ DataLabelsShowPercent = 3 # 百分比, 仅饼图
327
+ DataLabelsShowValue = 2 # 默认值
328
+
329
+
330
+ def initialize(active)
331
+ @chart = active
332
+ end
333
+
334
+ def chart_work
335
+ @chart
336
+ end
337
+
338
+ # 标签选项
339
+ def now_table
340
+ #@chart.SeriesCollection(n).DataLabels
341
+ num = @chart.SeriesCollection.Count
342
+ num.times do |t|
343
+ t += 1
344
+ yield @chart.SeriesCollection(t).DataLabels
345
+ end
346
+ end
347
+
348
+ # 修改标题
349
+ def title=(name)
350
+ @chart.HasTitle = true
351
+ @chart.ChartTitle.Characters.Text = name
352
+ end
353
+
354
+ # 这是原数据地址, 以每列数据作为一个系列
355
+ def source=(range)
356
+ @chart.SetSourceData(range, 2)
357
+ end
358
+
359
+ # 更改图形类型
360
+ def type=(c_type)
361
+ @chart.ChartType = c_type
362
+ end
363
+
364
+ # 设置X轴名称, 只用于条形图
365
+ def axes_x=(name)
366
+ @chart.Axes(1,1).HasTitle = true
367
+ @chart.Axes(1,1).AxisTitle.Characters.Text = name
368
+ end
369
+
370
+ # 设置Y轴名称, 只用于条形图
371
+ def axes_y=(name)
372
+ @chart.Axes(2,1).HasTitle = true
373
+ @chart.Axes(2,1).AxisTitle.Characters.Text = name
374
+ end
375
+
376
+ # 设置坐标轴格式, 刻度单位
377
+ def axes_unit(int)
378
+ @chart.Axes(2).MajorUnit = int
379
+ @chart.Axes(2).MinorUnit = int
380
+ end
381
+
382
+ # 修改样式
383
+ # 通过录制宏可以查看样式编号
384
+ # 条形图中203 比较好看
385
+ # 饼图中 251, 254 比较好看
386
+ def style=(int)
387
+ @chart.ChartStyle = int
388
+ data_label
389
+ end
390
+
391
+ # 添加饼图的百分比
392
+ def data_label(type=DataLabelsShowLabelAndPercent)
393
+
394
+ # 应用标签选项
395
+ @chart.ApplyDataLabels(type)
396
+
397
+ # 取消标签选项的系列名称
398
+ now = @chart.SeriesCollection(1).DataLabels
399
+ now.ShowSeriesName = false
400
+
401
+ # 将图例放到右边
402
+ now = @chart.Legend
403
+ now.Position = -4152
404
+ end
405
+
406
+ # 标签系列名称开关
407
+ def series_name=(bool)
408
+ now_table do |n|
409
+ n.ShowSeriesName = bool
410
+ end
411
+ end
412
+
413
+ # 标签类别名称开关
414
+ def category_name=(bool)
415
+ now_table do |n|
416
+ n.ShowCategoryName = bool
417
+ end
418
+ end
419
+
420
+ # 标签值开关
421
+ def value=(bool)
422
+ now_table do |n|
423
+ n.ShowValue = bool
424
+ n.ShowLegendKey = 0 unless bool
425
+ n.Separator = " " unless bool
426
+ end
427
+ end
428
+
429
+ end
430
+
431
+ end
432
+
433
+
data/lib/office.rb ADDED
@@ -0,0 +1,9 @@
1
+ load 'string.rb'
2
+ load 'os.rb'
3
+
4
+ # excel
5
+ load 'excel_wps.rb'
6
+ load 'excel_office.rb'
7
+
8
+ # word
9
+ load 'word_wps.rb'
data/lib/os.rb ADDED
@@ -0,0 +1,24 @@
1
+ module OS
2
+ class << self
3
+ def os_family
4
+ case RUBY_PLATFORM
5
+ when /ix/i, /ux/i, /gnu/i,
6
+ /sysv/i, /solaris/i,
7
+ /sunos/i, /bsd/i
8
+ "unix"
9
+ when /win/i, /ming/i
10
+ "windows"
11
+ else
12
+ "other"
13
+ end
14
+ end
15
+
16
+ def windows?
17
+ self.os_family == "windows" ? true : false
18
+ end
19
+
20
+ def linux?
21
+ self.os_family == "unix" ? true : false
22
+ end
23
+ end
24
+ end
data/lib/string.rb ADDED
@@ -0,0 +1,29 @@
1
+ module Toolkit; end
2
+ module Toolkit::String
3
+ class << self
4
+
5
+ # 终极解决方案
6
+ # 遇到了 invalid byte sequence in UTF-8 (ArgumentError) 问题
7
+ # 解决办法参考 https://stackoverflow.com/questions/29877310/invalid-byte-sequence-in-utf-8-argumenterror
8
+ def safe(str)
9
+ case OS.os_family
10
+ when "unix"
11
+ if ! str.valid_encoding?
12
+ str = str.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
13
+ end
14
+ when "windows"
15
+ #str = str.force_encoding("UTF-8")
16
+ str = str.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
17
+ end
18
+ return str
19
+ end
20
+
21
+ # 改写成安全的Windows书写方式
22
+ def safe_path(path)
23
+ if OS.windows?
24
+ path.gsub!("/", "\\")
25
+ end
26
+ end
27
+ end
28
+ end
29
+