開發環境:C# + EXCEL2003 + VS2008
問題:
當使用如下代碼從gridview導出數據到excel後,無法從excel取出數據,具體如下:
1、原使用的代碼:
protected void ExcelOut_Click(object sender, EventArgs e)
{
Response.Clear(); //清除緩衝區流中的所有內容輸出
Response.Buffer = true; //
Response.Charset = ""; //設置輸出流的http字符集
//保存附件用"attachment;filename=bang.xls";在線打開用"online;filename=bang.xls"
//可以是.doc、.xls、.txt、.htm、
Response.AppendHeader("Content-Disposition", "attachment;filename=bang.xls");
Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");//設置輸出流爲簡體中文
//設置輸出文件類型爲excel文件。保存爲word時,應爲"application/ms-word"
//可以爲application/ms-excel、application/ms-word、application/ms-txt、application/ms-html、或其他瀏覽器可直接支持文檔
Response.ContentType = "application/vnd.ms-excel";
this.EnableViewState = false; //關閉保存視圖狀態
System.Globalization.CultureInfo myCItrad = new System.Globalization.CultureInfo("ZH-CN", true);//區域設置
System.IO.StringWriter oStringWriter = new System.IO.StringWriter(myCItrad);
System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
DepartList.RenderControl(oHtmlTextWriter); //將DataGrid(dgBang)中的內容輸出到oHtmlTextWriter
Response.Write(oStringWriter.ToString());
Response.End();//將當前所有緩衝的輸出發送到客戶端,並停止該頁執行
}
使用這段代碼確實可以導出數據,並以excel的格式保存在用戶的客戶端電腦裏,但當使用到這些導出的excel文件時就出問題了,下面代碼是使用這些excel文件的:
前臺頁面需要一個控件配合:
<asp:FileUpload ID="ExcelIn" runat="server" Width="250px" CssClass="inputcss"
Height="16px" ></asp:FileUpload> <font face="宋體"></font>
protected void ExcelInButton_Click(object sender, EventArgs e)
{
string strFilePath = "";
string serverPath = "";
//通過控件來獲取用戶待上傳的excel文件名,這個excel文件其實是上面程序產生的文件
strFilePath = ExcelIn.PostedFile.FileName;
// strFilePath = strFilePath.Substring(strFilePath.LastIndexOf("."));
// 獲取系統時間生成附件名
//strFilePath = DateTime.Now.ToFileTime().ToString() + strFilePath;
// 將附件保存到服務器上
ExcelIn.PostedFile.SaveAs(("D:") + "\\空調標杆附件\\" + strFilePath);
serverPath = "D:\\空調標杆附件\\" + strFilePath;
string strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + serverPath + ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1'";
OleDbConnection ExcelConn = new OleDbConnection(strCon);
try
{
string strCom = "SELECT * FROM [Sheet1$]";
<span style="background-color: rgb(255, 102, 102);">ExcelConn.Open();</span>
OleDbDataAdapter myCommand = new OleDbDataAdapter(strCom, ExcelConn);
DataSet ds = new DataSet();
myCommand.Fill(ds, "[Sheet1$]");<pre> //由於excel列名“當月效益”和gridview中“當月效益”指定的數據源"效益"不一樣,無法匹配數據源,因此要把excel中列名改爲“效益”
ds.Tables[0].Columns["當月效益"].ColumnName = "效益";
DepartList.DataSource = ds;
DepartList.DataBind();
ExcelConn.Close();
}
catch (MembershipCreateUserException ex)
{
ExcelConn.Close();
Response.Write("<script>alert('導入內容:" + ex.Message + "')</script>");
}
}
當程序運行到下面程序時,會報錯,錯誤代碼爲:"外部表不是預期的格式錯誤"。
ExcelConn.Open();
分析:
當我們用2003以上版本的excel打開這些excel文件時,會出現:文件格式和擴展名不匹配,文件可能已損壞或不安全。
這說明我們用
ExcelOut_Click(object sender, EventArgs e)
來生成excel文件的方法不是很好,我在網上查閱了大量資料,按照各種方法也沒有解決這個問題,然後我用另外一種方法從gridview導出數據到excel,結果成功了,不再出現:“文件格式和擴展名不匹配,文件可能已損壞或不安全”這個錯誤。代碼如下:
/// <summary>
/// 將數據從gridview導入到本地excel,文件保存在D:\\調試文件\\中,文件名爲當時的時間
/// </summary>
/// <param name="FileName"></param>
private void SaveFile(String FileName)
{
try
{
string fileNameString = "D:\\調試文件\\" + FileName;
//驗證strFileName是否爲空或值無效
if (fileNameString.Trim() == " ")
{ return; }
//定義表格內數據的行數和列數
int rowscount = DepartList.Rows.Count;
int colscount = DepartList.Columns.Count;
//行數必須大於0
if (rowscount <= 0)
{
System.Web.HttpContext.Current.Response.Write("沒有數據可供保存");
return;
}
//列數必須大於0
if (colscount <= 0)
{
System.Web.HttpContext.Current.Response.Write("沒有數據可供保存");
return;
}
//行數不可以大於65536
if (rowscount > 65536)
{
System.Web.HttpContext.Current.Response.Write("數據記錄數太多(最多不能超過65536條)");
return;
}
//列數不可以大於255
if (colscount > 255)
{
System.Web.HttpContext.Current.Response.Write("數據記錄行數太多,不能保存");
return;
}
Microsoft.Office.Interop.Excel.Application objExcel = null;
Microsoft.Office.Interop.Excel.Workbook objWorkbook = null;
Microsoft.Office.Interop.Excel.Worksheet objsheet = null;
try
{
//申明對象
objExcel = new Microsoft.Office.Interop.Excel.Application();
objWorkbook = objExcel.Workbooks.Add(true);
objsheet = (Microsoft.Office.Interop.Excel.Worksheet)objWorkbook.ActiveSheet;
//設置EXCEL不可見
objExcel.Visible = false;
//設置列寬
//objExcel.Range objRng = objsheet.get_Range(objsheet.Cells[1, 1], objsheet.Cells[1, 1]);
//向Excel中寫入表格的表頭
int displayColumnsCount = 1;
for (int i = 0; i <= DepartList.Columns.Count - 1; i++)
{
if (DepartList.Columns[i].Visible == true)
{
objExcel.Cells[1, displayColumnsCount] = DepartList.Columns[i].HeaderText.Trim();
displayColumnsCount++;
}
}
//向Excel中逐行逐列寫入表格中的數據
for (int row = 0; row <= DepartList.Rows.Count - 1; row++)
{
displayColumnsCount = 1;
for (int col = 0; col < 2; col++)
{
if (DepartList.Columns[col].Visible == true)
{
try
{
if (DepartList.Rows[row].Cells[col].Text != null)
{
objExcel.Cells[row + 2, displayColumnsCount] = DepartList.Rows[row].Cells[col].Text.ToString();
}
else
{
objExcel.Cells[row + 2, displayColumnsCount] = "";
}
displayColumnsCount++;
}
catch (Exception ex)
{
System.Web.HttpContext.Current.Response.Write(ex.Message);
}
}
}
}
//保存文件
objWorkbook.SaveAs(fileNameString, true, null, null, null,
null, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlShared, true, true, true,
true, true);
objExcel.Quit();
}
catch (Exception error)
{
System.Web.HttpContext.Current.Response.Write(error.Message);
return;
}
}
catch (Exception ex)
{
System.Web.HttpContext.Current.Response.Write(ex.Message);
}
}
上面的函數只能實現從gridview導出數據到excel,要使得用戶可以下載生成的文件,那得用到另一個函數:
/// 下載服務器上已有文件
/// </summary>
/// <param name="fileName">保存到客戶端時的文件名</param>
/// <param name="filePath">下載文件在服務器上所在物理路徑全名</param>
public static void DownloadFile(String fileName, String filePath)
{
FileInfo fileInfo = new FileInfo(filePath);
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ClearContent();
System.Web.HttpContext.Current.Response.ClearHeaders();
System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
System.Web.HttpContext.Current.Response.AddHeader("Content-Length", fileInfo.Length.ToString());
System.Web.HttpContext.Current.Response.AddHeader("Content-Transfer-Encoding", "binary");
System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream";
System.Web.HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
System.Web.HttpContext.Current.Response.WriteFile(fileInfo.FullName);
System.Web.HttpContext.Current.Response.Flush();
System.Web.HttpContext.Current.Response.End();
}
使用方法如下:
protected void ExcelOut_Click(object sender, EventArgs e)
{
string FileName = DateTime.Now.ToFileTime().ToString() + ".xls";
string FilePath = "D:\\調試文件\\" + FileName;
SaveFile(FileName);
DownloadFile(FileName, FilePath);
}