详讲:C#快速导出多个sheet到excel的两种方法(Cell和Range方法), 解决了(导入时外部表不是预期的格式)...

C# 导出的表加载时报错:外部表不是预期的格式。的解决方案

在网卡找了一些Excel导出的方法,大部分能导出,但时不能将导出的Excel导入。总是报:外部表不是预期的格式

找了好久终于找到了解决方案。

这是本人整理修改后的的可以实现导出导入的方法。供大家学习参考,方法就是用一个没问题的Excel模板,在模板的基础上进行操作。

引用空间:using Excel = Microsoft.Office.Interop.Excel;

//导出方案
private void simpleButton5_Click(object sender, EventArgs e)
{

saveFileDialog1.Filter = "Execl files (*.xls)|*.xls";
saveFileDialog1.FilterIndex = 0;
saveFileDialog1.RestoreDirectory = true;
saveFileDialog1.CreatePrompt = true;
saveFileDialog1.Title = "导出文件保存路径";
saveFileDialog1.FileName = "方案文件";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
BLL.T_Project bllProject = new BLL.T_Project();
System.Data.DataTable dt1 = bllProject.GetList("1=1 order by Start_State desc ,id desc").Tables[0];

BLL.T_Plan bll_Plan = new BLL.T_Plan();
System.Data.DataTable dt2 =bll_Plan.GetList("plan_type='***' order by id asc").Tables[0];
System.Data.DataTable dt3 =bll_Plan.GetList("plan_type='***' order by id asc").Tables[0];

DataSet ds = new DataSet();
ds.Tables.Add(GetTable(dt1, "T_Project"));
ds.Tables.Add(GetTable(dt2, "T_PlanJian"));
ds.Tables.Add(GetTable(dt3, "T_PlanPing"));

string strName = saveFileDialog1.FileName;
ToExcelSheet(ds, "mysheet", strName);
}

//ToExcel2(gridView2, saveFileDialog1);
}
public System.Data.DataTable GetTable(System.Data.DataTable Dt, string tablename)
{

Dt.AcceptChanges();

System.Data.DataTable m_Dt = new System.Data.DataTable();//定义一个新的Table

int m_RowCount = (int)Dt.Rows.Count;//定义一个变量,值为Dt的行数

int m_ColCount = Dt.Columns.Count;//定义一个变量,值为Dt的列数

for (int j = 0; j < m_ColCount; j++)
{

m_Dt.Columns.Add(Dt.Columns[j].ColumnName, Dt.Columns[j].DataType);

}

for (int i = 0; i < m_RowCount; i++)//增加记录在临时表中
{

if (Dt.Rows[i].RowState.ToString() != "Deleted")
{

DataRow NewRow = m_Dt.NewRow();//定义一个新行为m_Dt表的新行

for (int j = 0; j < m_ColCount; j++)//循环行
{

NewRow[j] = Dt.Rows[i][j];

}

m_Dt.Rows.Add(NewRow);//临时表中增加新行

}

}

m_Dt.TableName = tablename;

return m_Dt;//返回临时表

}



#region 导出到excel多sheet的两种方法

private void ToExcelSheet(DataSet ds, string sheetName, string strFileName)
{
//Exsel模板
string templetFile = System.Windows.Forms.Application.StartupPath + @"/Temp/template.xls";
System.Reflection.Missing miss = System.Reflection.Missing.Value;
//创建EXCEL对象appExcel,Workbook对象,Worksheet对象,Range对象
Excel.Application appExcel;
appExcel = new Excel.Application();

Excel.Workbook workbookData;
Excel.Worksheet worksheetData;
Excel.Range rangedata;
//设置对象不可见
appExcel.Visible = false;
/* 在调用Excel应用程序,或创建Excel工作簿之前,记着加上下面的两行代码
* 这是因为Excel有一个Bug,如果你的操作系统的环境不是英文的,而Excel就会在执行下面的代码时,报异常。
*/
System.Globalization.CultureInfo CurrentCI = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
//以新建的方式
// workbookData = appExcel.Workbooks.Add(miss);
//以模板的方式
workbookData = appExcel.Workbooks.Open(templetFile, miss, miss, miss, miss, miss,miss, miss, miss, miss, miss, miss, miss);


try
{
for (int k = 0; k < ds.Tables.Count; k++)
{
worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add(Missing.Value, Missing.Value, Missing.Value, Missing.Value);
//worksheetData = (Excel.Worksheet)workbookData.Worksheets.Add();
worksheetData.Name = ds.Tables[k].TableName;

if (ds.Tables[k] != null)
{
//表字段(表头)
for (int i = 0; i < ds.Tables[k].Columns.Count; i++)
{
worksheetData.Cells[i + 1] = ds.Tables[k].Columns[i].ColumnName.ToString();
}
//先给Range对象一个范围为A2开始,Range对象可以给一个CELL的范围,也可以给例如A1到H10这样的范围
//因为第一行已经写了表头,所以所有数据都应该从A2开始
rangedata = worksheetData.get_Range("A2", miss);
Excel.Range xlRang = null;
//总行数
int iRowCount = ds.Tables[k].Rows.Count;
//iEachSize当前每次导出的行数的页面大小,可以自己设置
int iEachSize = 2;
//已导出的行数 ,当前每次导出的行数大小
int iParstedRow = 0, iCurrSize = 0;

//列数
int iColumnAccount = ds.Tables[k].Columns.Count;
//在内存中声明一个iEachSize×iColumnAccount的数组,iEachSize是每次最大存储的行数,iColumnAccount就是存储的实际列数
object[,] objVal = new object[iEachSize, iColumnAccount];

iCurrSize = iEachSize;
/*
//方法一:Cell方法导出表数据
for (int i = 0; i < ds.Tables[k].Rows.Count; i++)
{
for (int j = 0; j < ds.Tables[k].Columns.Count; j++)
{
//worksheetData.Cells[i + 2, j + 1] = ds.Tables[k].Rows[i][j].ToString();
objVal[i, j] = ds.Tables[k].Rows[i][j].ToString();
}
System.Windows.Forms.Application.DoEvents();
}
*/
//方法二:Range方法导出表数据(此方法导出很快,建议用此方法)
while (iParstedRow < iRowCount)
{
//总行数-已导出行数;剩余行数是否小于页面大小,小于的话,当前导出行数为余行
if ((iRowCount - iParstedRow) < iEachSize)
{
iCurrSize = iRowCount - iParstedRow;
}
for (int i = 0; i < iCurrSize; i++)
{
for (int j = 0; j < iColumnAccount; j++)
{
//objVal[i, j] = gridView[j, i + iParstedRow].Value.ToString();
objVal[i, j] = ds.Tables[k].Rows[i + iParstedRow][j].ToString();

}

System.Windows.Forms.Application.DoEvents();
}

/*
* 建议使用设置断点研究下哈
* 例如A1到H10的意思是从A到H,第一行到第十行
* 下句很关键,要保证获取workSheet中对应的Range范围
* 下句实际上是得到这样的一个代码语句xlRang = worksheetData.get_Range("A2","H100");
* 注意看实现的过程
* 'A' + iColumnAccount - 1这儿是获取你的最后列,A的数字码为65,大家可以仔细看下是不是得到最后列的字母
* iParstedRow + iCurrSize + 1获取最后行
* 若WHILE第一次循环的话这应该是A2,最后列字母+最后行数字
* iParstedRow + 2要注意,每次循环这个值不一样,他取决于你每次循环RANGE取了多大,也就是iEachSize设置值的大小哦
*/
xlRang = worksheetData.get_Range("A" + ((int)(iParstedRow + 2)).ToString(), ((char)('A' + iColumnAccount - 1)).ToString() + ((int)(iParstedRow + iCurrSize + 1)).ToString());
// 调用Range的Value2属性,把内存中的值赋给Excel
xlRang.Value2 = objVal;
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRang);
xlRang = null;
//已导出的行数=已导出的行数+当前导出行数
iParstedRow = iParstedRow + iCurrSize;
}
}

worksheetData.Columns.EntireColumn.AutoFit();
workbookData.Saved = true;

}


//workbookData.SaveAs(strFileName);
workbookData.SaveAs(strFileName + "", miss, miss, miss, miss, miss, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, miss, miss, miss);
appExcel.Quit();
// 别忘了在结束程序之前恢复你的环境!
System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
GC.Collect();
XtraMessageBox.Show("导出完成!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch {
appExcel.Quit();
//调用方法关闭EXCEL进程,大家可以试下不用的话如果程序不关闭在进程里一直会有EXCEL.EXE这个进程并锁定你的EXCEL表格
this.KillSpecialExcel(appExcel);
// 别忘了在结束程序之前恢复你的环境!
System.Threading.Thread.CurrentThread.CurrentCulture = CurrentCI;
GC.Collect();
XtraMessageBox.Show("导出失败!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);

}

}
#endregion

、、、、、、、、、、、、、、、

此方法本人测试通过,如有不完善地方,望指出!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值