1 using Microsoft.Office.Interop.Excel;
2 using System;
3 using System.IO;
4 using System.Reflection;
5
6 namespace ECIT.ProjectManagementSystem.Common
7 {
8 public class ExcelHelper : IDisposable
9 {
10 #region 成员变量
11
12 private object missing = Missing.Value;
13 private Application app;
14 private Workbook workBook;
15 public Worksheet workSheet;
16
17 public void setWorkSheet(int i)
18 {
19 workSheet = (Worksheet)workBook.Worksheets[i];
20 }
21
22 #endregion 成员变量
23
24 #region 公共属性
25
26 /// <summary>
27 /// WorkSheet数量
28 /// </summary>
29 public int WorkSheetCount
30 {
31 get { return workBook.Sheets.Count; }
32 }
33
34 #endregion 公共属性
35
36 #region 构造函数
37
38 /// <summary>
39 /// 构造函数,新建一个工作簿
40 /// </summary>
41 public ExcelHelper()
42 {
43 app = new Application();
44 workBook = app.Workbooks.Add(Type.Missing);
45 workSheet = (Worksheet)app.Worksheets[1];
46 }
47
48 /// <summary>
49 /// 构造函数,打开一个已有的工作簿
50 /// </summary>
51 /// <param name="fileName">Excel文件名</param>
52 public ExcelHelper(string fileName)
53 {
54 if (!File.Exists(fileName))
55 throw new Exception("指定路径的Excel文件不存在!");
56
57 app = new Application();
58
59 workBook = app.Workbooks.Open(fileName,
60 Type.Missing, Type.Missing, Type.Missing, Type.Missing,
61 Type.Missing, Type.Missing, Type.Missing, Type.Missing,
62 Type.Missing, Type.Missing, Type.Missing, Type.Missing);
63
64 workSheet = (Worksheet)app.Worksheets[1];
65 }
66
67 #endregion 构造函数
68
69 #region 工作表操作
70
71 /// <summary>
72 /// 删除工作表
73 /// </summary>
74 /// <param name="i">工作表的序号</param>
75 public void RemoveSheet(int i)
76 {
77 Worksheet worksheet = (Worksheet)app.Worksheets[i];
78 app.DisplayAlerts = false;
79 worksheet.Delete();
80 app.DisplayAlerts = true;
81 }
82
83 /// <summary>
84 /// 增加工作表
85 /// </summary>
86 /// <param name="i">工作表的序号</param>
87 public void AddSheet(int i)
88 {
89 app.Worksheets.Add(Type.Missing, Type.Missing, i, XlSheetType.xlWorksheet);
90 }
91
92 #endregion 工作表操作
93
94 #region 单元格操作
95
96 /// <summary>
97 /// 获得最大行号
98 /// </summary>
99 /// <returns></returns>
100 public int GetUsedRangeRow()
101 {
102 return workSheet.UsedRange.Rows.Count;
103 }
104
105 /// <summary>
106 /// 获得最大列号
107 /// </summary>
108 /// <returns></returns>
109 public int GetUsedRangeColumn()
110 {
111 return workSheet.UsedRange.Columns.Count;
112 }
113
114 /// <summary>
115 /// 获取单元格的文本内容
116 /// </summary>
117 /// <param name="row">行号</param>
118 /// <param name="column">列号</param>
119 /// <returns></returns>
120 public string GetCellText(int row, int column)
121 {
122 if (workSheet == null)
123 return null;
124 Range range = (Range)workSheet.Cells[row, column];
125 string cellContent = (range.Value2 == null) ? "" : range.Text.ToString();
126 return cellContent;
127 }
128
129 /// <summary>
130 /// 赋值单元格
131 /// </summary>
132 /// <param name="excelRange"></param>
133 /// <param name="value"></param>
134 public void SetValue(ExcelRange excelRange, object value)
135 {
136 workSheet.Range[excelRange.ToString()].Value2 = value;
137 }
138
139 /// <summary>
140 /// 设置字体大小
141 /// </summary>
142 /// <param name="excelRange"></param>
143 /// <param name="size"></param>
144 public void SetFontSize(ExcelRange excelRange, int size)
145 {
146 workSheet.Range[excelRange.ToString()].Font.Size = size;
147 }
148
149 /// <summary>
150 /// 设置字体颜色
151 /// </summary>
152 /// <param name="excelRange"></param>
153 /// <param name="color"></param>
154 public void SetFontColor(ExcelRange excelRange, System.Drawing.Color color)
155 {
156 workSheet.Range[excelRange.ToString()].Font.Color = color;
157 }
158
159 /// <summary>
160 /// 设置单元格背景色
161 /// </summary>
162 /// <param name="excelRange"></param>
163 /// <param name="color"></param>
164 public void SetBackgroundColor(ExcelRange excelRange, System.Drawing.Color color)
165 {
166 workSheet.Range[excelRange.ToString()].Interior.Color = color;
167 }
168
169 /// <summary>
170 /// 设置字体粗体
171 /// </summary>
172 /// <param name="excelRange"></param>
173 /// <param name="isBold"></param>
174 public void SetFontBold(ExcelRange excelRange, bool isBold)
175 {
176 workSheet.Range[excelRange.ToString()].Font.Bold = isBold; //设置字体粗体。
177 }
178
179 /// <summary>
180 /// 设置是否有下划线
181 /// </summary>
182 /// <param name="excelRange"></param>
183 /// <param name="isUnderline"></param>
184 public void SetUnderline(ExcelRange excelRange, bool isUnderline)
185 {
186 workSheet.Range[excelRange.ToString()].Font.Underline = isUnderline;
187 }
188
189 /// <summary>
190 /// 设置字体
191 /// </summary>
192 /// <param name="excelRange"></param>
193 /// <param name="fontname"></param>
194 public void SetFontName(ExcelRange excelRange, string fontname)
195 {
196 workSheet.Range[excelRange.ToString()].Font.Name = fontname;
197 }
198
199 /// <summary>
200 /// 设置单元格宽度
201 /// </summary>
202 /// <param name="excelRange"></param>
203 /// <param name="columnwidth"></param>
204 public void SetColumnWidth(ExcelRange excelRange, int columnwidth)
205 {
206 workSheet.Range[excelRange.ToString()].ColumnWidth = columnwidth;
207 }
208
209 /// <summary>
210 /// 文本自动换行
211 /// </summary>
212 /// <param name="excelRange"></param>
213 /// <param name="isWrapText"></param>
214 public void SetWrapText(ExcelRange excelRange, bool isWrapText)
215 {
216 workSheet.Range[excelRange.ToString()].WrapText = isWrapText;
217 }
218
219 /// <summary>
220 /// 文本横向对齐方式
221 /// </summary>
222 /// <param name="excelRange"></param>
223 /// <param name="xlHAlign"></param>
224 public void SetHorizontalAlignment(ExcelRange excelRange, XlHAlign xlHAlign)
225 {
226 workSheet.Range[excelRange.ToString()].HorizontalAlignment = xlHAlign;
227 }
228
229 /// <summary>
230 /// 文本垂直对齐方式
231 /// </summary>
232 /// <param name="excelRange"></param>
233 /// <param name="xlHAlign"></param>
234 public void SetVerticalAlignment(ExcelRange excelRange, XlHAlign xlHAlign)
235 {
236 workSheet.Range[excelRange.ToString()].VerticalAlignment = xlHAlign;
237 }
238
239 /// <summary>
240 /// 自动调整列宽
241 /// </summary>
242 /// <param name="excelRange"></param>
243 public void FitColumn(ExcelRange excelRange)
244 {
245 workSheet.Range[excelRange.ToString()].EntireColumn.AutoFit();
246 }
247
248 /// <summary>
249 /// 设置单元格边框
250 /// </summary>
251 /// <param name="excelRange"></param>
252 public void SetBorderAround(ExcelRange excelRange, XlLineStyle LineStyle, XlBorderWeight BorderWeight)
253 {
254 workSheet.Range[excelRange.ToString()].BorderAround(LineStyle, BorderWeight, XlColorIndex.xlColorIndexAutomatic, 15); //设置区域边框
255 }
256
257 /// <summary>
258 /// 单元格合并动作
259 /// </summary>
260 /// <param name="excelRange"></param>
261 /// <param name="IsMergeCells"></param>
262 public void MergeCell(ExcelRange excelRange, bool IsMergeCells)
263 {
264 workSheet.Range[excelRange.ToString()].MergeCells = IsMergeCells;
265 }
266
267 #endregion 单元格操作
268
269 #region 图表绘制
270
271 /// <summary>
272 /// 3D柱状图
273 /// </summary>
274 /// <param name="excelRange"></param>
275 /// <param name="left"></param>
276 /// <param name="top"></param>
277 /// <param name="width"></param>
278 /// <param name="height"></param>
279 /// <param name="title"></param>
280 /// <param name="xTitle"></param>
281 /// <param name="yTitle"></param>
282 /// <param name="plotBy">XlRowCol.xlRows=数据系列在一列中 XlRowCol.xlColumns=数据系列在一行中</param>
283 public void Draw3DColumn(ExcelRange excelRange, double left, double top, double width, double height, string title, string xTitle, string yTitle, XlRowCol plotBy)
284 {
285 ChartObjects charts = (ChartObjects)workSheet.ChartObjects(Type.Missing);
286 ChartObject chartObj = charts.Add(left, top, width, height);
287 Chart chart = chartObj.Chart;
288 chart.ChartWizard(workSheet.Range[excelRange.ToString()], XlChartType.xl3DColumn, missing, plotBy, 1, 1, true, title, xTitle, yTitle, 1);
289 }
290
291 /// <summary>
292 /// 3D柱状图
293 /// </summary>
294 /// <param name="excelRange"></param>
295 /// <param name="startRange"></param>
296 /// <param name="width"></param>
297 /// <param name="height"></param>
298 /// <param name="title"></param>
299 /// <param name="xTitle"></param>
300 /// <param name="yTitle"></param>
301 /// <param name="plotBy">XlRowCol.xlRows=数据系列在一列中 XlRowCol.xlColumns=数据系列在一行中</param>
302 public void Draw3DColumn(ExcelRange excelRange, ExcelRange startRange, double width, double height, string title, string xTitle, string yTitle, XlRowCol plotBy)
303 {
304 Draw3DColumn(excelRange, Convert.ToDouble(workSheet.Range[startRange.ToString()].Left), Convert.ToDouble(workSheet.Range[startRange.ToString()].Top), width, height, title, xTitle, yTitle, plotBy);
305 }
306
307 /// <summary>
308 /// 3D饼图
309 /// </summary>
310 /// <param name="excelRange"></param>
311 /// <param name="left"></param>
312 /// <param name="top"></param>
313 /// <param name="width"></param>
314 /// <param name="height"></param>
315 /// <param name="title"></param>
316 public void Draw3DPie(ExcelRange excelRange, double left, double top, double width, double height, string title)
317 {
318 ChartObjects charts = (ChartObjects)workSheet.ChartObjects(Type.Missing);
319 ChartObject chartObj = charts.Add(left, top, width, height);
320 Chart chart = chartObj.Chart;
321 chart.ChartWizard(workSheet.Range[excelRange.ToString()], XlChartType.xl3DPie, missing, XlRowCol.xlColumns, 1, 1, true, title, missing, missing, 1);
322 }
323
324 /// <summary>
325 /// 3D饼图
326 /// </summary>
327 /// <param name="excelRange"></param>
328 /// <param name="startRange"></param>
329 /// <param name="width"></param>
330 /// <param name="height"></param>
331 /// <param name="title"></param>
332 public void Draw3DPie(ExcelRange excelRange, ExcelRange startRange, double width, double height, string title)
333 {
334 Draw3DPie(excelRange, Convert.ToDouble(workSheet.Range[startRange.ToString()].Left), Convert.ToDouble(workSheet.Range[startRange.ToString()].Top), width, height, title);
335 }
336
337 #endregion 图表绘制
338
339 #region 文件操作
340
341 /// <summary>
342 /// 保存文件
343 /// </summary>
344 /// <param name="fileName"></param>
345 public void SaveFile(string fileName)
346 {
347 try
348 {
349 workBook.RefreshAll();
350 workBook.SaveAs(fileName, missing, missing, missing, missing, missing, XlSaveAsAccessMode.xlNoChange, missing, missing, missing, missing);
351 }
352 catch (Exception e)
353 {
354 Console.WriteLine(e);
355 throw e;
356 }
357 }
358
359 #endregion 文件操作
360
361 #region 资源回收
362
363 private bool disposed = false;
364
365 ~ExcelHelper()
366 {
367 //必须为false
368 Dispose(false);
369 }
370
371 public void Dispose()
372 {
373 //必须为true
374 Dispose(true);
375 //通知垃圾回收机制不再调用终结器(析构器)
376 GC.SuppressFinalize(this);
377 }
378
379 private void Dispose(bool disposing)
380 {
381 if (disposed)
382 {
383 return;
384 }
385 if (disposing)
386 {
387 // 清理托管资源
388 }
389
390 // 清理非托管资源
391 if (app != null)
392 {
393 app.Quit();
394 app = null;
395 }
396
397 GC.Collect();
398 GC.WaitForPendingFinalizers();
399
400 //让类型知道自己已经被释放
401 disposed = true;
402 }
403
404 #endregion 资源回收
405 }
406
407 /// <summary>
408 /// EXCEL单元格操作范围
409 /// </summary>
410 public class ExcelRange
411 {
412 public string RangeString { get; set; }
413
414 public ExcelRange(string RangeString)
415 {
416 this.RangeString = RangeString;
417 }
418
419 /// <summary>
420 /// 输入Excel的行号和列号获得范围
421 /// </summary>
422 /// <param name="x">列号</param>
423 /// <param name="y">行号</param>
424 public ExcelRange(int x, int y)
425 {
426 this.RangeString = IntToLetter(x) + y.ToString();
427 }
428
429 public ExcelRange(int x1, int y1, int x2, int y2)
430 {
431 this.RangeString = IntToLetter(x1) + y1.ToString() + ":" + IntToLetter(x2) + y2.ToString();
432 }
433
434 public ExcelRange(ExcelRange from, ExcelRange to)
435 {
436 this.RangeString = from.RangeString + ":" + to.RangeString;
437 }
438
439 static public implicit operator ExcelRange(string value)
440 {
441 return new ExcelRange(value);
442 }
443
444 static public implicit operator string (ExcelRange ExcelRange)
445 {
446 return ExcelRange.RangeString;
447 }
448
449 public override string ToString()
450 {
451 return RangeString;
452 }
453
454 /// <summary>
455 /// 将Excel列的整数索引值转换为字符索引值
456 /// </summary>
457 /// <param name="n"></param>
458 /// <returns></returns>
459 public static string IntToLetter(int n)
460 {
461 if (n > 700)
462 throw new Exception("索引超出范围,Excel的列索引不能超过700!");
463
464 int i = Convert.ToInt32(n / 26);
465 int j = n % 26;
466
467 char c1 = Convert.ToChar(i + 64);
468 char c2 = Convert.ToChar(j + 64);
469
470 if (n > 26)
471 return c1.ToString() + c2.ToString();
472 else if (n == 26)
473 return "Z";
474 else
475 return c2.ToString();
476 }
477 }
478 }