using Infragistics.Win.UltraWinGrid;
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace Core.StlMes.Client.PlnSaleOrd
{
/**/
///
/// 功能说明: 为套用模板输出Excel定制,并对数据进行分页
///
public class ExcelHelper
{
protected string templetFile = null;
protected string outputFile = null;
protected object missing = Missing.Value;
///
/// 构造函数,需指定模板文件和输出文件完整路径
///
/// Excel模板文件路径
/// 输出Excel文件路径
public ExcelHelper(string templetFilePath, string outputFilePath)
{
if (templetFilePath == null)
throw new Exception(" Excel模板文件路径不能为空! ");
if (!File.Exists(templetFilePath))
throw new Exception(" 指定路径的Excel模板文件不存在! ");
this.templetFile = templetFilePath;
this.outputFile = outputFilePath;
if (CheckPath() == false)
throw new Exception(" 输出Excel文件路径不能为空! ");
}
///
/// 获取Cells单元格的值
///
/// 第x行,Excel的起始列为1
/// 第y列,Excel的起始行为1
/// object
public string GetCell_Value(int x, int y,Microsoft.Office.Interop.Excel.Worksheet sheet)
{
if (sheet == null) { return ""; }
object[] Parameters_Cells = new object[2] { x, y }; //第x行,第y列
object m_objCells = sheet.GetType().InvokeMember("Cells", BindingFlags.GetProperty | BindingFlags.OptionalParamBinding, null, sheet, Parameters_Cells);
if (m_objCells == null)
{
return "";
}
object m_objCellsValue = sheet.GetType().InvokeMember("Value", BindingFlags.GetProperty, null, m_objCells, new object[0]);
if (m_objCellsValue == null)
{
return "";
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(m_objCells);
GC.GetTotalMemory(true);
return m_objCellsValue.ToString();
}
///
/// 获取WorkSheet数量
///
/// 记录总行数
/// 每WorkSheet行数
private int GetSheetCount(int rowCount, int rows)
{
int n = rowCount % rows; // 余数
if (n == 0)
return rowCount / rows;
else
return Convert.ToInt32(rowCount / rows) + 1;
}
///
/// 将二维数组数据写入Excel文件(套用模板并分页)
///
/// 二维数组
/// 每个WorkSheet写入多少行数据
/// 行索引-从1开始
/// 列索引-从1开始
/// WorkSheet前缀名,比如:前缀名为“Sheet”,那么WorkSheet名称依次为“Sheet-1,Sheet-2”
public bool ArrayToExcel(object[,] arr, int rows, int top, int left, string sheetPrefixName)
{
int rowCount = arr.GetLength(0); // 二维数组行数(一维长度)
int colCount = arr.GetLength(1); // 二维数据列数(二维长度)
int sheetCount = this.GetSheetCount(rowCount, rows); // WorkSheet个数
if (sheetPrefixName == null || sheetPrefixName.Trim() == "")
sheetPrefixName = " Sheet ";
// 创建一个Application对象并使其可见
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
app.Visible = false;
try
{
// 打开模板文件,得到WorkBook对象
Microsoft.Office.Interop.Excel.Workbook workBook = app.Workbooks._Open(templetFile, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing);
// 得到WorkSheet对象
Microsoft.Office.Interop.Excel.Worksheet workSheet = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Sheets.get_Item(1);
// 复制sheetCount-1个WorkSheet对象
for (int i = 1; i < sheetCount; i++)
{
((Microsoft.Office.Interop.Excel.Worksheet)workBook.Worksheets.get_Item(i)).Copy(missing, workBook.Worksheets[i]);
}
#region 将二维数组数据写入Excel
//将二维数组数据写入Excel
for (int i = 1; i <= sheetCount; i++)
{
int startRow = (i - 1) * rows; // 记录起始行索引
int endRow = i * rows; // 记录结束行索引
// 若是最后一个WorkSheet,那么记录结束行索引为源DataTable行数
if (i == sheetCount)
endRow = rowCount;
// 获取要写入数据的WorkSheet对象,并重命名
Microsoft.Office.Interop.Excel.Worksheet sheet = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Worksheets.get_Item(i);
sheet.Name = sheetPrefixName + " - " + i.ToString();
//设定输出部分的样式
Microsoft.Office.Interop.Excel.Range excelRange = sheet.get_Range(SeqToXlsCol[left] + (top + startRow - (i - 1) * rows),
SeqToXlsCol[left + colCount - 1] + (top + endRow - 1 - (i - 1) * rows));
//excelRange.NumberFormatLocal = "@";
excelRange.Borders.LineStyle = 1;
excelRange.Font.Size = 9;
excelRange.Font.Name = "Arial";
List param = new List();
for (int row = 0; row < rowCount; row++)
{
for (int col = 0; col < colCount; col++)
{
if (arr[row, col].ToString().Length > 500)
{
ValuesPoint value = new ValuesPoint();
value.Values = arr[row, col];
value.Row = row;
value.Col = col;
arr[row, col] = "";
param.Add(value);
}
}
}
//string _BeginPoint = SeqToXlsCol[left] + (top + startRow - (i - 1) * rows);
//string _EndPoint = SeqToXlsCol[left + colCount - 1] + (top + endRow - 1 - (i - 1) * rows);
//SetRangeArray_Value(app, sheet, _BeginPoint, _EndPoint, arr);
//设定header 居中粗体
//sheet.get_Range(IFCF.SeqToXlsCol[left] + top + ":" + IFCF.SeqToXlsCol[left + colCount - 1] + top).Font.Bold = true;
//sheet.get_Range(IFCF.SeqToXlsCol[left] + top + ":" + IFCF.SeqToXlsCol[left + colCount - 1] + top).HorizontalAlignment = XlHAlign.xlHAlignCenter;
// 将二维数组中的数据写入WorkSheet
sheet.get_Range(SeqToXlsCol[left] + (top + startRow - (i - 1) * rows),
SeqToXlsCol[left + colCount - 1] + (top + endRow - 1 - (i - 1) * rows)).Value2 = arr;
for (int cout = 0; cout < param.Count; cout++)
{
int row = param[cout].Row;
int col = param[cout].Col;
sheet.Cells[top + row-startRow, left + col] = param[cout].Values;
}
//for (int j = 0; j < endRow - startRow; j++)
//{
// for (int k = 0; k < colCount; k++)
// {
// sheet.Cells[top + j, left + k] = arr[startRow + j, k];
// }
//}
//自动调整列宽
//sheet.Cells.EntireColumn.AutoFit();
}
#endregion
// 输出Excel文件并退出
//保存Excel的时候,不弹出是否保存的窗口直接进行保存
app.DisplayAlerts = false;
workBook._SaveAs(outputFile, missing, missing, missing, missing, missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, 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);
ExcelProecssKill(app);
workSheet = null;
workBook = null;
app = null;
GC.Collect();
}
catch (Exception ex)
{
ExcelProecssKill(app);
Debug.WriteLine(ex.Message);
MessageBox.Show(ex.Message);
return false;
}
finally
{
ExcelProecssKill(app);
}
return true;
}
///
/// 将二维数组数据写入Excel文件(套用模板并分页)
///
/// 二维数组
/// 行索引-从1开始
/// 列索引-从1开始
/// WorkSheet前缀名,比如:前缀名为“Sheet”,那么WorkSheet名称依次为“Sheet-1,Sheet-2”
public bool ArrayToExcel(object[,] arr, int top, int left, string sheetPrefixName)
{
int rowCount = arr.GetLength(0); // 二维数组行数(一维长度)
int colCount = arr.GetLength(1); // 二维数据列数(二维长度)
if (sheetPrefixName == null || sheetPrefixName.Trim() == "")
sheetPrefixName = " Sheet ";
// 创建一个Application对象并使其可见
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
app.Visible = false;
try
{
// 打开模板文件,得到WorkBook对象
Microsoft.Office.Interop.Excel.Workbook workBook = app.Workbooks._Open(templetFile, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing);
// 得到WorkSheet对象
Microsoft.Office.Interop.Excel.Worksheet workSheet = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Sheets.get_Item(1);
#region 将二维数组数据写入Excel
//将二维数组数据写入Excel
//for (int i = 1; i <= sheetCount; i++)
//{
//int startRow = (i - 1) * rows; // 记录起始行索引
//int endRow = i * rows; // 记录结束行索引
//// 若是最后一个WorkSheet,那么记录结束行索引为源DataTable行数
//if (i == sheetCount)
// endRow = rowCount;
// 获取要写入数据的WorkSheet对象,并重命名
Microsoft.Office.Interop.Excel.Worksheet sheet = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Worksheets.get_Item(1);
sheet.Name = sheetPrefixName + " - 1";
//设定输出部分的样式
Microsoft.Office.Interop.Excel.Range excelRange = sheet.get_Range(SeqToXlsCol[left] + top,
SeqToXlsCol[left + colCount - 1] + (top + rowCount - 1));
//excelRange.NumberFormatLocal = "@";
excelRange.Borders.LineStyle = 1;
excelRange.Font.Size = 9;
excelRange.Font.Name = "Arial";
List param = new List();
for (int row = 0; row < rowCount; row++)
{
for (int col = 0; col < colCount; col++)
{
if (arr[row, col].ToString().Length > 500)
{
ValuesPoint value = new ValuesPoint();
value.Values = arr[row, col];
value.Row = row;
value.Col = col;
arr[row, col] = "";
param.Add(value);
}
}
}
//string _BeginPoint = SeqToXlsCol[left] + (top + startRow - (i - 1) * rows);
//string _EndPoint = SeqToXlsCol[left + colCount - 1] + (top + endRow - 1 - (i - 1) * rows);
//SetRangeArray_Value(app, sheet, _BeginPoint, _EndPoint, arr);
//设定header 居中粗体
//sheet.get_Range(IFCF.SeqToXlsCol[left] + top + ":" + IFCF.SeqToXlsCol[left + colCount - 1] + top).Font.Bold = true;
//sheet.get_Range(IFCF.SeqToXlsCol[left] + top + ":" + IFCF.SeqToXlsCol[left + colCount - 1] + top).HorizontalAlignment = XlHAlign.xlHAlignCenter;
// 将二维数组中的数据写入WorkSheet
sheet.get_Range(SeqToXlsCol[left] + top,
SeqToXlsCol[left + colCount - 1] + (top + rowCount - 1)).Value2 = arr;
for (int cout = 0; cout < param.Count; cout++)
{
int row = param[cout].Row;
int col = param[cout].Col;
sheet.Cells[top + row, left + col] = param[cout].Values;
}
//for (int j = 0; j < endRow - startRow; j++)
//{
// for (int k = 0; k < colCount; k++)
// {
// sheet.Cells[top + j, left + k] = arr[startRow + j, k];
// }
//}
//自动调整列宽
//sheet.Cells.EntireColumn.AutoFit();
#endregion
// 输出Excel文件并退出
//保存Excel的时候,不弹出是否保存的窗口直接进行保存
app.DisplayAlerts = false;
workBook._SaveAs(outputFile, missing, missing, missing, missing, missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, 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);
ExcelProecssKill(app);
workSheet = null;
workBook = null;
app = null;
GC.Collect();
}
catch (Exception ex)
{
ExcelProecssKill(app);
Debug.WriteLine(ex.Message);
MessageBox.Show(ex.Message);
return false;
}
finally
{
ExcelProecssKill(app);
}
return true;
}
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
///
/// 对Excel的进程进行处理
///
///
public static void ExcelProecssKill(Microsoft.Office.Interop.Excel.Application excel)
{
try
{
if (excel != null)
{
IntPtr t = new IntPtr(excel.Hwnd); //得到这个句柄,具体作用是得到这块内存入口
int k = 0;
GetWindowThreadProcessId(t, out k); //得到本进程唯一标志k
System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k); //得到对进程k的引用
p.Kill(); //关闭进程k
}
}
catch (System.Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
///
/// 验证输出文件的路径,如果没有就新
///
/// true or false
private bool CheckPath()
{
try
{
string tempPath = outputFile.Substring(0, outputFile.LastIndexOf("\\"));
if (Directory.Exists(tempPath) == false)
{
Directory.CreateDirectory(tempPath);
}
if (File.Exists(outputFile) == true)
{
File.Delete(outputFile);
//File.Move(outputFile, outputFile + "_" + DateTime.Now.ToString("yyyyMMddHHmmss"));
}
return true;
}
catch (System.Exception ex)
{
Debug.WriteLine(ex.Message);
return false;
}
}
///
/// 读取Grid数据,并按模板格式排列成二维数组
///
/// grid表格
/// 模板表头行索引-从1开始
/// 模板表头列索引-从1开始
/// 二维数组
public string[,] setModelArr(UltraGrid grid, int top, int left)
{
int count = 0; //模板表头列数
string[,] arr = null;
DateTime beforeTime;
DateTime afterTime;
// 创建一个Application对象并使其可见
beforeTime = DateTime.Now;
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application(); //new Excel.ApplicationClass();
app.Visible = true;
afterTime = DateTime.Now;
try
{
// 打开模板文件,得到WorkBook对象
Microsoft.Office.Interop.Excel.Workbook workBook = app.Workbooks._Open(templetFile, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing);
// 得到WorkSheet对象
Microsoft.Office.Interop.Excel.Worksheet workSheet = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Sheets.get_Item(1);
ArrayList headGourp = new ArrayList();
for (int k = left; k < workSheet.Columns.Count; k++)
{
string head = GetCell_Value(top, k, workSheet);
headGourp.Add(head);
if (head.Equals(""))
{
count = k - left;
break;
}
}
arr = new string[grid.Rows.Count, count];
//读取grid数据到二维数组中
for (int k = left, j = 0; k < count + left; k++, j++)
{
string head = headGourp[j].ToString();
//string head = GetCell_Value(top, k, workSheet);
int rows = 0;
for (int i = 0; i < grid.DisplayLayout.Bands[0].Columns.Count; i++)
{
string gridhead = grid.DisplayLayout.Bands[0].Columns[i].Header.Caption;
if (head.Equals(gridhead))
{
foreach (UltraGridRow uRow in grid.Rows)
{
arr[rows, k - 1] = uRow.Cells[i].Value.ToString();
rows++;
}
break;
}
}
}
app.Workbooks.Close();
app.Application.Quit();
app.Quit();
}
catch (Exception ex)
{
ExcelProecssKill(app);
Debug.WriteLine(ex.Message);
return arr;
}
finally
{
ExcelProecssKill(app);
}
return arr;
}
///
/// 读取DataTable数据,并按模板格式排列成二维数组
///
/// DataTable
/// 模板表头行索引-从1开始
/// 模板表头列索引-从1开始
/// 二维数组
public string[,] setModelArr(System.Data.DataTable dt, int top, int left)
{
int count = 0; //模板表头列数
string[,] arr = null;
DateTime beforeTime;
DateTime afterTime;
// 创建一个Application对象并使其可见
beforeTime = DateTime.Now;
Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application(); //new Excel.ApplicationClass();
app.Visible = true;
afterTime = DateTime.Now;
try
{
// 打开模板文件,得到WorkBook对象
Microsoft.Office.Interop.Excel.Workbook workBook = app.Workbooks._Open(templetFile, missing, missing, missing, missing, missing,
missing, missing, missing, missing, missing, missing, missing);
// 得到WorkSheet对象
Microsoft.Office.Interop.Excel.Worksheet workSheet = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Sheets.get_Item(1);
ArrayList headGourp = new ArrayList();
for (int k = left; k < workSheet.Columns.Count; k++)
{
string head = GetCell_Value(top, k, workSheet);
headGourp.Add(head);
if (head.Equals(""))
{
count = k - left;
break;
}
}
arr = new string[dt.Rows.Count, count];
//读取DataTable数据到二维数组中
for (int k = left, j = 0; k < count + left; k++, j++)
{
string head = headGourp[j].ToString();
//string head = GetCell_Value(top, k, workSheet);
int rows = 0;
for (int i = 0; i < dt.Columns.Count; i++)
{
string dthead = dt.Columns[i].Caption;
if (head.Equals(dthead))
{
foreach (DataRow dr in dt.Rows)
{
arr[rows, k - 1] = dr[i].ToString();
rows++;
}
break;
}
}
}
app.Workbooks.Close();
app.Application.Quit();
app.Quit();
}
catch (Exception ex)
{
ExcelProecssKill(app);
Debug.WriteLine(ex.Message);
return arr;
}
finally
{
ExcelProecssKill(app);
}
return arr;
}
///
/// 列标号,Excel最大列数是256
///
public static string[] SeqToXlsCol = new string[] {"",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ",
"BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BK", "BL", "BM", "BN", "BO", "BP", "BQ", "BR", "BS", "BT", "BU", "BV", "BW", "BX", "BY", "BZ",
"CA", "CB", "CC", "CD", "CE", "CF", "CG", "CH", "CI", "CJ", "CK", "CL", "CM", "CN", "CO", "CP", "CQ", "CR", "CS", "CT", "CU", "CV", "CW", "CX", "CY", "CZ",
"DA", "DB", "DC", "DD", "DE", "DF", "DG", "DH", "DI", "DJ", "DK", "DL", "DM", "DN", "DO", "DP", "DQ", "DR", "DS", "DT", "DU", "DV", "DW", "DX", "DY", "DZ",
"EA", "EB", "EC", "ED", "EE", "EF", "EG", "EH", "EI", "EJ", "EK", "EL", "EM", "EN", "EO", "EP", "EQ", "ER", "ES", "ET", "EU", "EV", "EW", "EX", "EY", "EZ",
"FA", "FB", "FC", "FD", "FE", "FF", "FG", "FH", "FI", "FJ", "FK", "FL", "FM", "FN", "FO", "FP", "FQ", "FR", "FS", "FT", "FU", "FV", "FW", "FX", "FY", "FZ",
"GA", "GB", "GC", "GD", "GE", "GF", "GG", "GH", "GI", "GJ", "GK", "GL", "GM", "GN", "GO", "GP", "GQ", "GR", "GS", "GT", "GU", "GV", "GW", "GX", "GY", "GZ",
"HA", "HB", "HC", "HD", "HE", "HF", "HG", "HH", "HI", "HJ", "HK", "HL", "HM", "HN", "HO", "HP", "HQ", "HR", "HS", "HT", "HU", "HV", "HW", "HX", "HY", "HZ",
"IA", "IB", "IC", "ID", "IE", "IF", "IG", "IH", "II", "IJ", "IK", "IL", "IM", "IN", "IO", "IP", "IQ", "IR", "IS", "IT", "IU", "IV"
};
///
/// 将二维数组 写入 excel
///
/// 起始位置 如"A1"
/// 终止位置 如"B5"
/// 写入的二维数组的值,可以是各种数据类型
/// bool,是否正确写入
public bool SetRangeArray_Value(object m_objApp,object m_objSheet,string _BeginPoint, string _EndPoint, object[,] _Array_Value)
{
if (m_objApp == null) { return false; }
if (m_objSheet == null) { return false; }
try
{
//得到range数组
//object[] Parameters_rangeArray = new object[] { "A1", "B5" };
object[] Parameters_rangeArray = new object[] { _BeginPoint, _EndPoint };
object m_objRangeArray = m_objSheet.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, m_objSheet, Parameters_rangeArray);
if (m_objRangeArray == null)
{
Console.WriteLine("出错啦: range == null,请检查range的设置。");
}
//************************
//得到写入值
Object[] ParametersArray_WriteValue = new Object[1];
ParametersArray_WriteValue[0] = _Array_Value; //赋值:数值类型=int
//******************
m_objRangeArray.GetType().InvokeMember("Value2", BindingFlags.SetProperty, null, m_objRangeArray, ParametersArray_WriteValue);
System.Runtime.InteropServices.Marshal.ReleaseComObject(m_objRangeArray);
GC.GetTotalMemory(true);
return true;
}
catch (Exception ex)
{
MessageBox.Show("写入错误!错误原因:" + ex.Message);
return false;
}
}
///
/// 退出excel.exe的编辑模式 Edit Mode
///
//public void SetApp_Exit_EditMode()
//{
// if (m_objApp == null) { return; }
// if (m_objSheet == null) { return; }
// while (true)
// {
// try
// {
// this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
// bool bAppReady = (bool)m_objApp.GetType().InvokeMember("Ready", BindingFlags.GetProperty, null, m_objApp, null);
// this.Cursor = System.Windows.Forms.Cursors.Arrow;
// break; //如果excel.exe退出了编辑模式则退出循环
// }
// catch
// {
// myWin32API.SetForegroundWindow(this.appSubWinHandle);
// myWin32API.SetFocus(this.appSubWinHandle);
// //System.Threading.Thread.Sleep(100);
// System.Windows.Forms.SendKeys.SendWait("{ESC}"); //发送ESC键
// //System.Windows.Forms.SendKeys.Send("{ESC}"); //发送ESC键
// //System.Threading.Thread.Sleep(100);
// }
// }
//}
}
class ValuesPoint
{
private object values;
public object Values
{
get { return values; }
set { values = value; }
}
private int row;
public int Row
{
get { return row; }
set { row = value; }
}
private int col;
public int Col
{
get { return col; }
set { col = value; }
}
}
}