C# 导出到Excel (有模板、分页)
来源:互联网 发布:oracle dmp更新数据库 编辑:程序博客网 时间:2024/06/05 20:20
把数据导出到Excel以供打印有很多种方式,大概有5种,这里不多说。同时也有很多要求,如
一 要求:导出Excel 格式如下:
(1)要分页,即n个表显示大量数据,并且每个表都要有表头和列名
(2)列名要有单位
(3)边框样式:内边框细实线,外边框粗实线
(4)各行数据要适应数据宽度,所有列要打印到一个页面上
(5)不能有空行边框
二 解决方法:调用com组件、使用模板的方式
*优点:因为模板的格式相对固定,有表头样式、规定了必要的字段、某字段格式如日期、列名有单位、边框样式、列
名适应打印出的数据宽度
*需解决的问题:
1 dataTable表字段与模板Excel字段名不一致,dataTable表字段可能没有单位, 而模板Excel字段要有单位
2 dataTable表字段数目不定、顺序不定(由于页面上有“自定义显示”设置,用户可任意选择字段、调整顺序),
但要和模板Excel字段列数和列的顺序分别相对应
三 代码
(1)1.1横向分页,即n个Sheet,n个表
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
using System.Diagnostics;
using System.Collections;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Data;
public class CommonToExcel
{
protected string outputFile = null;
protected object missing = Missing.Value;
DateTime beforeTime;
DateTime afterTime;
private static ArrayList cols = null; //存储WorkSheet对象的所有列名
private static Dictionary<string, string> Dic = null;
private DataTable myDataTable;
/// <summary>
/// DataTable
/// </summary>
public DataTable MyDataTable
{
get { return myDataTable; }
set { myDataTable = value; }
}
/// <summary>
/// 将DataTable数据写入Excel文件(套用模板并分页)
/// </summary>
/// <param name="outputFile">输出文件名</param>
/// <param name="rows">每个WorkSheet写入多少行数据</param>
/// <param name="top">行索引</param>
/// <param name="left">列索引</param>
/// <param name="sheetPrefixName">WorkSheet前缀名,比如:前缀名为“Sheet”,那么WorkSheet名称依次为“Sheet-1,Sheet-2”</param>
public bool ExcelCopy(string outputFile, int rows, int top, int left, string sheetPrefixName)
{
Excel._Application App;
Excel._Workbook workBook; //模板
bool Isopen;
if (sheetPrefixName == null || sheetPrefixName.Trim() == "")
sheetPrefixName = "Sheet";
try
{
beforeTime = DateTime.Now;
GetWorkbook(outputFile, out App, out workBook, out Isopen);
if (workBook == null) { return false; }
//得到WorkSheet对象
Excel.Worksheet workSheet = (Excel.Worksheet)workBook.Sheets.get_Item(1);
MatchCols(myDataTable, workSheet);
TablToExcel(myDataTable, rows, top, left, sheetPrefixName, workBook);
Kill(ref App, ref workBook, ref workSheet);
return true;
}
catch
{ return false; }
}
/// <summary>
/// 获取WorkSheet数量
/// </summary>
/// <param name="rowCount">记录总行数</param>
/// <param name="rows">每WorkSheet行数</param>
private int GetSheetCount(int rowCount, int rows)
{
int n = rowCount % rows; //余数
if (n == 0)
return rowCount / rows;
else
return Convert.ToInt32(rowCount / rows) + 1;
}
private void GetWorkbook(string filePatch, out Excel._Application App, out Excel._Workbook workbook, out bool Isopen)
{
Isopen = IsOpen(filePatch);
if (Isopen == true)
{
workbook = GetWorkbook(out App, filePatch, "");
}
else
{
//创建一个Application对象,默认不可见
App = new Excel.Application();
//App.Visible = true;
afterTime = DateTime.Now;
//打开文件,得到WorkBook对象
workbook = OpenWorkbook(App, filePatch, "");
}
}
private bool IsOpen(string patch)
{
bool fileopen = false;
try
{
System.IO.File.Move(patch, patch);
}
catch
{
fileopen = true;
}
return fileopen;
}
private Excel._Workbook GetWorkbook(out Excel._Application App, string patch, string Password)
{
Excel._Workbook templetWorkbook = null;
Excel._Workbook tempbook = null;
int iTries = 0;
TryAgain:
try
{
//templetWorkbook = System.Runtime.InteropServices.Marshal.BindToMoniker(patch) as Excel._Workbook;
App = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
afterTime = DateTime.Now;
int x = App.Workbooks.Count;
for (int i = 0; i < x; i++)
{
tempbook = App.Workbooks.get_Item(i + 1);
if (tempbook.FullName.ToUpper() == patch.ToUpper())
{
templetWorkbook = tempbook;
break;
}
}
}
catch (Exception e)
{
throw e;
}
if (templetWorkbook == null)
{
iTries++;
if (iTries < 5)
{
System.Threading.Thread.Sleep(500); // Wait 1/2 seconds.
goto TryAgain; //resume code at the GetObject line
}
else
{
MessageBox.Show("Excel模板文件打开错误,请关闭正在使用的Excel文件后重试!");
}
}
return templetWorkbook;
}
private Excel._Workbook OpenWorkbook(Excel._Application App, string patch, string Password)
{
object m = Type.Missing;
Excel.Workbook templetWorkbook;
if (Password == "")
{
templetWorkbook = App.Workbooks.Open(patch, m, m, m, m, m, m, m, m, m, m, m, m, m, m);
}
else
{
templetWorkbook = App.Workbooks.Open(patch, m, m, m, Password, m, m, m, m, m, m, m, m, m, m);
}
return templetWorkbook;
}
private void TablToExcel(DataTable myDataTable, int rows, int top, int left, string sheetPrefixName, Excel._Workbook workBook)
{
int rowCount = myDataTable.Rows.Count; //源DataTable行数
int colCount = myDataTable.Columns.Count; //源DataTable列数
int sheetCount = this.GetSheetCount(rowCount, rows); //WorkSheet个数
//复制sheetCount-1个WorkSheet对象
for (int i = 1; i < sheetCount; i++)
{
((Excel.Worksheet)workBook.Worksheets.get_Item(i)).Copy(missing, workBook.Worksheets[i]);
}
//将源DataTable数据写入Excel
#region 将源DataTable数据写入Excel
try
{
for (int i = 1; i <= sheetCount; i++)
{
int startRow = (i - 1) * rows; //记录起始行索引
int endRow = i * rows; //记录结束行索引
//若是最后一个WorkSheet,那么记录结束行索引为源DataTable行数
if (i == sheetCount)
endRow = rowCount;
//获取要写入数据的WorkSheet对象,并重命名
Excel.Worksheet sheet = (Excel.Worksheet)workBook.Worksheets.get_Item(i);
sheet.Name = sheetPrefixName + "-" + i.ToString();
string temp;
string ExCol;
int j = 0;
//将myDataTable中的数据写入WorkSheet
for (j = 0; j < endRow - startRow; j++) //循环每页的行
{
for (int k = 0; k < cols.Count; k++)
{
ExCol = cols[k].ToString(); //Excel里的
if (Dic.ContainsKey(ExCol))
{
string va = Dic[ExCol].ToString();
temp = myDataTable.Rows[startRow + j][va].ToString();
sheet.Cells[top + j, left + k] = temp;
}
}
}
if (i == sheetCount) //设置最后一页的格式
{
Excel.Range excelRange = sheet.get_Range(sheet.Cells[3, 1], sheet.Cells[top - 1 + j, cols.Count]);
excelRange.Borders.LineStyle = 1;
excelRange.BorderAround(Excel.XlLineStyle.xlContinuous, Excel.XlBorderWeight.xlMedium, Excel.XlColorIndex.xlColorIndexAutomatic, null);
Excel.Range excelRange1 = sheet.get_Range(sheet.Cells[top + j, 1], sheet.Cells[top + 25, cols.Count]);
excelRange1.Borders.LineStyle = Excel.XlLineStyle.xlLineStyleNone;
}
sheet.PageSetup.CenterFooter = string.Format("第{0}页,共{1}页", i, sheetCount);
}
}
catch (Exception ex)
{
//Log.WriteFile("TablToExcel.Msg=" + ex.Message, "log.ini");
}
#endregion
}
private static void MatchCols(DataTable myDataTable, Excel.Worksheet workSheet)
{
string cont;
cols = new ArrayList();
try
{
//得到WorkSheet对象的所有列名,cols存
int n = 1;
while (true)
{
cont = ((Excel.Range)workSheet.Cells[3, n]).Text.ToString();//第三行
if (n > 5 && cont == "") break; //Excel表里列名为空 m>myDataTable.Columns.Count
cont = PartStr(cont);
if (cont != "")
cols.Add(cont);
n++;
}
//得到对应列的DataTable的列名,dic存
Dic = new Dictionary<string, string>(); //以去掉单位的列名为键,以全列名为值
for (int m = 0; m < myDataTable.Columns.Count; m++)
{
string col = cols[m].ToString();
DataColumn dc = myDataTable.Columns[m];
string newName = PartStr(dc.ColumnName);
if (cols.Contains(newName))
{
Dic.Add(newName, dc.ColumnName);
}
}
}
catch
{ }
}
/// <summary>
/// 将字符串(列名)去掉单位
/// </summary>
/// <param name="cont"></param>
/// <returns></returns>
private static string PartStr(string cont)
{
StringBuilder sb = new StringBuilder();
Regex regex = new Regex("[/u4e00-/u9fa5]+", RegexOptions.Compiled);
char[] stringChar = cont.ToCharArray();
for (int i = 0; i < stringChar.Length; i++)
{
if (regex.IsMatch((stringChar[i]).ToString())) //if((int)q[i]>=0x4E00 && (int)q[i]<=0x9FA5)
{
sb.Append(stringChar[i]);
}
}
return sb.ToString();
// for (int i = 0; i < stringChar.Length; i++)
// {
// int code = Char.ConvertToUtf32(cont, i);
// if(code>=4E00 && code<=9FFF)
// }
}
private void Kill(ref Excel._Application App, ref Excel._Workbook workBook, ref Excel.Worksheet workSheet)
{
try
{
workBook.Save();
//workBook.SaveAs(outputFile, missing, missing, missing, missing, missing, Excel.XlSaveAsAccessMode.xlExclusive, missing, missing, missing, missing, missing);
//workBook.SaveAs("当前状态1.xls ", missing, missing, missing, missing, missing, Excel.XlSaveAsAccessMode.xlExclusive, missing, missing, missing, missing, missing);
workBook.Close(null, null, null);
App.Workbooks.Close();
App.Application.Quit();
App.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(App);
workSheet = null;
//fileworkSheet = null;
workBook = null;
//fileWorkbook = null;
App = null;
GC.Collect();
}
catch (Exception e)
{
throw e;
}
finally
{
Process[] myProcesses;
DateTime startTime;
myProcesses = Process.GetProcessesByName("Excel");
//得不到Excel进程ID,暂时只能判断进程启动时间
foreach (Process myProcess in myProcesses)
{
startTime = myProcess.StartTime;
if (startTime > beforeTime && startTime < afterTime)
{
myProcess.Kill();
}
}
}
}
}
1.2 纵向分页,即1个Sheet,n个表
关键代码:
private void TablToExcel(DataTable myDataTable, int rows, int top, int left)
{
int dataTop = 0; //Excel每一页的空行
int rowCount = myDataTable.Rows.Count; //源DataTable行数
int colCount = myDataTable.Columns.Count; //源DataTable列数
int sheetCount = this.GetSheetCount(rowCount, rows); //WorkSheet个数
string v = NumberToChar(cols.Count);
Excel.Range templetRange = fileXlSheet.get_Range("A1", v + "30");
//templetRange.Copy(missing);
//将源DataTable数据写入Excel
#region 将源DataTable数据写入Excel
try
{
for (int i = 1; i <= sheetCount; i++)
{
int startRow = (i - 1) * rows; //记录起始行索引
int endRow = i * rows; //记录结束行索引
//若是最后一个WorkSheet,那么记录结束行索引为源DataTable行数
if (i == sheetCount)
endRow = rowCount;
dataTop = WhereIsNull(fileXlSheet,rows);
Excel.Range fileRange = fileXlSheet.get_Range("A" + dataTop.ToString(), v + (rows + 4 + dataTop).ToString());//(rows+5-1+dataTop)
templetRange.Copy(fileRange);
//fileRange._PasteSpecial(Excel.XlPasteType.xlPasteAll, Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);
string temp;
string ExCol;
int j = 0;
//将myDataTable中的数据写入WorkSheet
for (j = 0; j < endRow - startRow; j++) //循环每页的行
{
for (int k = 0; k < cols.Count; k++)
{
ExCol = cols[k].ToString(); //cols[k].ToString(); //数据表里现有的
if (Dic.ContainsKey(ExCol))
{
string va = Dic[ExCol].ToString();
temp = myDataTable.Rows[startRow + j][va].ToString();
fileXlSheet.Cells[top + dataTop + j, left + k] = temp;
}
}
}
if (i == sheetCount) //设置最后一页的格式
{
Excel.Range excelRange = fileXlSheet.get_Range(fileXlSheet.Cells[dataTop + 2, 1], fileXlSheet.Cells[top - 1 + dataTop + j, cols.Count]);
excelRange.Borders.LineStyle = 1;
excelRange.BorderAround(Excel.XlLineStyle.xlContinuous, Excel.XlBorderWeight.xlMedium, Excel.XlColorIndex.xlColorIndexAutomatic, null);
Excel.Range excelRange1 = fileXlSheet.get_Range(fileXlSheet.Cells[top + dataTop + j, 1], fileXlSheet.Cells[dataTop + rows + 4, cols.Count]);
excelRange1.Borders.LineStyle = Excel.XlLineStyle.xlLineStyleNone;
}
//设置最后一行的格式
Excel.Range excelRange2 = fileXlSheet.get_Range(fileXlSheet.Cells[top + dataTop + j, 1], fileXlSheet.Cells[top + dataTop + j, cols.Count]);
excelRange2.Merge(missing);
excelRange2.Value2 = string.Format("第{0}页,共{1}页", i, sheetCount);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
//Log.WriteFile("TablToExcel.Msg=" + ex.Message, "log.ini");
}
#endregion
}
///
/// 把1,2,3,...,35,36转换成A,B,C,...,Y,Z
///
/// 要转换成字母的数字(数字范围在闭区间[1,26])
///
private string NumberToChar(int number)
{
string va = "";
try
{
if (1 <= number && 26 >= number)
{
int num = number + 64;
System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
byte[] btNumber = new byte[] { (byte)num };
va = asciiEncoding.GetString(btNumber);
}
}
catch
{
//Log.WriteFile("NumberToChar.Msg=Excel列名数量过多", "log.ini");
}
return va;
}
private int WhereIsNull(Excel._Worksheet Sheet,int rows)
{
string temp;
int j = 0;
for (int i = 1; i < 65535; i++)
{
temp = ((Excel.Range)Sheet.Cells[i, 1]).Text.ToString();
if (temp == "")
{
j = i;
break;
}
else
{
i += rows + 4; //rows+5-1
}
}
return j;
}
(2)调用代码
string Patch = Application.StartupPath + "//日报//";
string templetFile = Patch + "出油_模板.xls";
string outputFile = Patch + string.Format("{0:yyMMddHHmm}", DateTime.Now) + "出油.xls";
if (System.IO.Directory.Exists(Patch) != true) //"日报//"
System.IO.Directory.CreateDirectory(Patch);
if (!System.IO.File.Exists(templetFile))
{
MessageBox.Show("没有找到模板!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return false;
}
if (!System.IO.File.Exists(outputFile))
{
try
{
System.IO.File.Copy(templetFile, outputFile, false);
}
catch (Exception except)
{ MessageBox.Show("error", "error"); }
}
CommonToExcel toExcel = new CommonToExcel();
toExcel.MyDataTable = myDataTable;
if (toExcel.ExcelCopy(outputFile, 25, 4, 1, "sheet") == true)
{
MessageBox.Show("报表导出成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
- C# 导出到Excel (有模板、分页)
- C# 导出数据到Excel模板中
- C#导出Excel|导出数据到Excel模板文件里
- asp.net 导出数据到Excel模板分页
- c#导出数据至excel模板中,可分页
- C# 实现Excel导出 加载模板 导入数据到模板
- C# excel模板导出
- Excel导出java实例(有模板)
- c# 导出table中的数据到模板excel中
- C# 简单将数据导出到Excel模板流程
- C#导出到EXCEL
- C#导出到EXCEL
- C#导出到EXCEL
- C#导出到EXCEL
- C#导出到excel
- c#导出到excel
- c# 导出到Excel
- C#导出到EXCEL
- VB.NET类型转换相关运算符应用技巧分享
- liunx 下的串口通信
- ubuntu 9.04下安装xdebug和kcachegrind
- js实现使元素在屏幕里上下左右居中
- 2008树形语法
- C# 导出到Excel (有模板、分页)
- 微软等公司数据结构+算法面试第1-80题汇总
- 5、进程间通信-信号量
- el表达式
- SQL Azure 一款强大的管理工具- Houston CTP 1(转+译)
- c#采集数据类
- 什么是BOM模型?
- Windows Azure SDK 1.3和新版Windows Azure 开发者门户(转+译)
- 带整理