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