office_elin 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+