2using System.IO;
3using System.Data;
4using System.Reflection;
5using System.Diagnostics;
6using cfg = System.Configuration;
7//using Excel;
8
9namespace ExcelHelperTest
10{
11 /**//// <summary>
12 /// 功能說明:套用模板輸出Excel,並對數據進行分頁
13 /// 作 者:Lingyun_k
14 /// 創建日期:2005-7-12
15 /// </summary>
16 public class ExcelHelper
17 {
18 protected string templetFile = null;
19 protected string outputFile = null;
20 protected object missing = Missing.Value;
21
22 /**//// <summary>
23 /// 構造函數,需指定模板文件和輸出文件完整路徑
24 /// </summary>
25 /// <param name="templetFilePath">Excel模板文件路徑</param>
26 /// <param name="outputFilePath">輸出Excel文件路徑</param>
27 public ExcelHelper(string templetFilePath,string outputFilePath)
28 {
29 if(templetFilePath == null)
30 throw new Exception("Excel模板文件路徑不能爲空!");
31
32 if(outputFilePath == null)
33 throw new Exception("輸出Excel文件路徑不能爲空!");
34
35 if(!File.Exists(templetFilePath))
36 throw new Exception("指定路徑的Excel模板文件不存在!");
37
38 this.templetFile = templetFilePath;
39 this.outputFile = outputFilePath;
40
41 }
42
43 /**//// <summary>
44 /// 將DataTable數據寫入Excel文件(套用模板並分頁)
45 /// </summary>
46 /// <param name="dt">DataTable</param>
47 /// <param name="rows">每個WorkSheet寫入多少行數據</param>
48 /// <param name="top">行索引</param>
49 /// <param name="left">列索引</param>
50 /// <param name="sheetPrefixName">WorkSheet前綴名,比如:前綴名爲“Sheet”,那麼WorkSheet名稱依次爲“Sheet-1,Sheet-2”</param>
51 public void DataTableToExcel(DataTable dt,int rows,int top,int left,string sheetPrefixName)
52 {
53 int rowCount = dt.Rows.Count; //源DataTable行數
54 int colCount = dt.Columns.Count; //源DataTable列數
55 int sheetCount = this.GetSheetCount(rowCount,rows); //WorkSheet個數
56 DateTime beforeTime;
57 DateTime afterTime;
58
59 if(sheetPrefixName == null || sheetPrefixName.Trim() == "")
60 sheetPrefixName = "Sheet";
61
62 //創建一個Application對象並使其可見
63 beforeTime = DateTime.Now;
64 Excel.Application app = new Excel.ApplicationClass();
65 app.Visible = true;
66 afterTime = DateTime.Now;
67
68 //打開模板文件,得到WorkBook對象
69 Excel.Workbook workBook = app.Workbooks.Open(templetFile,missing,missing,missing,missing,missing,
70 missing,missing,missing,missing,missing,missing,missing);
71
72 //得到WorkSheet對象
73 Excel.Worksheet workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(1);
74
75 //複製sheetCount-1個WorkSheet對象
76 for(int i=1;i<sheetCount;i++)
77 {
78 ((Excel.Worksheet)workBook.Worksheets.get_Item(i)).Copy(missing,workBook.Worksheets[i]);
79 }
80
81 將源DataTable數據寫入Excel#region 將源DataTable數據寫入Excel
82 for(int i=1;i<=sheetCount;i++)
83 {
84 int startRow = (i - 1) * rows; //記錄起始行索引
85 int endRow = i * rows; //記錄結束行索引
86
87 //若是最後一個WorkSheet,那麼記錄結束行索引爲源DataTable行數
88 if(i == sheetCount)
89 endRow = rowCount;
90
91 //獲取要寫入數據的WorkSheet對象,並重命名
92 Excel.Worksheet sheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i);
93 sheet.Name = sheetPrefixName + "-" + i.ToString();
94
95 //將dt中的數據寫入WorkSheet
96 for(int j=0;j<endRow-startRow;j++)
97 {
98 for(int k=0;k<colCount;k++)
99 {
100 sheet.Cells[top + j,left + k] = dt.Rows[startRow + j][k].ToString();
101 }
102 }
103
104 //寫文本框數據
105 Excel.TextBox txtAuthor = (Excel.TextBox)sheet.TextBoxes("txtAuthor");
106 Excel.TextBox txtDate = (Excel.TextBox)sheet.TextBoxes("txtDate");
107 Excel.TextBox txtVersion = (Excel.TextBox)sheet.TextBoxes("txtVersion");
108
109 txtAuthor.Text = "KLY.NET的Blog";
110 txtDate.Text = DateTime.Now.ToShortDateString();
111 txtVersion.Text = "1.0.0.0";
112 }
113 #endregion
114
115 //輸出Excel文件並退出
116 try
117 {
118 workBook.SaveAs(outputFile,missing,missing,missing,missing,missing,Excel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing);
119 workBook.Close(null,null,null);
120 app.Workbooks.Close();
121 app.Application.Quit();
122 app.Quit();
123
124 System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet);
125 System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook);
126 System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
127
128 workSheet=null;
129 workBook=null;
130 app=null;
131
132 GC.Collect();
133 }
134 catch(Exception e)
135 {
136 throw e;
137 }
138 finally
139 {
140 Process[] myProcesses;
141 DateTime startTime;
142 myProcesses = Process.GetProcessesByName("Excel");
143
144 //得不到Excel進程ID,暫時只能判斷進程啓動時間
145 foreach(Process myProcess in myProcesses)
146 {
147 startTime = myProcess.StartTime;
148
149 if(startTime > beforeTime && startTime < afterTime)
150 {
151 myProcess.Kill();
152 }
153 }
154 }
155
156 }
157
158
159 /**//// <summary>
160 /// 獲取WorkSheet數量
161 /// </summary>
162 /// <param name="rowCount">記錄總行數</param>
163 /// <param name="rows">每WorkSheet行數</param>
164 private int GetSheetCount(int rowCount,int rows)
165 {
166 int n = rowCount % rows; //餘數
167
168 if(n == 0)
169 return rowCount / rows;
170 else
171 return Convert.ToInt32(rowCount / rows) + 1;
172 }
173
174
175 /**//// <summary>
176 /// 將二維數組數據寫入Excel文件(套用模板並分頁)
177 /// </summary>
178 /// <param name="arr">二維數組</param>
179 /// <param name="rows">每個WorkSheet寫入多少行數據</param>
180 /// <param name="top">行索引</param>
181 /// <param name="left">列索引</param>
182 /// <param name="sheetPrefixName">WorkSheet前綴名,比如:前綴名爲“Sheet”,那麼WorkSheet名稱依次爲“Sheet-1,Sheet-2”</param>
183 public void ArrayToExcel(string[,] arr,int rows,int top,int left,string sheetPrefixName)
184 {
185 int rowCount = arr.GetLength(0); //二維數組行數(一維長度)
186 int colCount = arr.GetLength(1); //二維數據列數(二維長度)
187 int sheetCount = this.GetSheetCount(rowCount,rows); //WorkSheet個數
188 DateTime beforeTime;
189 DateTime afterTime;
190
191 if(sheetPrefixName == null || sheetPrefixName.Trim() == "")
192 sheetPrefixName = "Sheet";
193
194 //創建一個Application對象並使其可見
195 beforeTime = DateTime.Now;
196 Excel.Application app = new Excel.ApplicationClass();
197 app.Visible = true;
198 afterTime = DateTime.Now;
199
200 //打開模板文件,得到WorkBook對象
201 Excel.Workbook workBook = app.Workbooks.Open(templetFile,missing,missing,missing,missing,missing,
202 missing,missing,missing,missing,missing,missing,missing);
203
204 //得到WorkSheet對象
205 Excel.Worksheet workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(1);
206
207 //複製sheetCount-1個WorkSheet對象
208 for(int i=1;i<sheetCount;i++)
209 {
210 ((Excel.Worksheet)workBook.Worksheets.get_Item(i)).Copy(missing,workBook.Worksheets[i]);
211 }
212
213 將二維數組數據寫入Excel#region 將二維數組數據寫入Excel
214 for(int i=1;i<=sheetCount;i++)
215 {
216 int startRow = (i - 1) * rows; //記錄起始行索引
217 int endRow = i * rows; //記錄結束行索引
218
219 //若是最後一個WorkSheet,那麼記錄結束行索引爲源DataTable行數
220 if(i == sheetCount)
221 endRow = rowCount;
222
223 //獲取要寫入數據的WorkSheet對象,並重命名
224 Excel.Worksheet sheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i);
225 sheet.Name = sheetPrefixName + "-" + i.ToString();
226
227 //將二維數組中的數據寫入WorkSheet
228 for(int j=0;j<endRow-startRow;j++)
229 {
230 for(int k=0;k<colCount;k++)
231 {
232 sheet.Cells[top + j,left + k] = arr[startRow + j,k];
233 }
234 }
235
236 Excel.TextBox txtAuthor = (Excel.TextBox)sheet.TextBoxes("txtAuthor");
237 Excel.TextBox txtDate = (Excel.TextBox)sheet.TextBoxes("txtDate");
238 Excel.TextBox txtVersion = (Excel.TextBox)sheet.TextBoxes("txtVersion");
239
240 txtAuthor.Text = "KLY.NET的Blog";
241 txtDate.Text = DateTime.Now.ToShortDateString();
242 txtVersion.Text = "1.0.0.0";
243 }
244 #endregion
245
246 //輸出Excel文件並退出
247 try
248 {
249 workBook.SaveAs(outputFile,missing,missing,missing,missing,missing,Excel.XlSaveAsAccessMode.xlExclusive,missing,missing,missing,missing);
250 workBook.Close(null,null,null);
251 app.Workbooks.Close();
252 app.Application.Quit();
253 app.Quit();
254
255 System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet);
256 System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook);
257 System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
258
259 workSheet=null;
260 workBook=null;
261 app=null;
262
263 GC.Collect();
264 }
265 catch(Exception e)
266 {
267 throw e;
268 }
269 finally
270 {
271 Process[] myProcesses;
272 DateTime startTime;
273 myProcesses = Process.GetProcessesByName("Excel");
274
275 //得不到Excel進程ID,暫時只能判斷進程啓動時間
276 foreach(Process myProcess in myProcesses)
277 {
278 startTime = myProcess.StartTime;
279
280 if(startTime > beforeTime && startTime < afterTime)
281 {
282 myProcess.Kill();
283 }
284 }
285 }
286
287 }
288 }
289}
290