Asp.net 从Excel读取图片并保存,无法从内存读取图片,Excel组件和相关IIS的配置及解决办法
2015-05-15 11:17
926 查看
Asp.net 从Excel读取图片并保存,无法从内存读取图片,Excel组件和相关IIS的配置及解决办法
目的:Asp.net web页面,读取Excel,(用的office组件),中的图片注意的事项:
只提供部分代码,因为重点是配置。
1:要想从Excel里读取图片,只能用剪贴板的方面将图片复制到内存然后再保存图片。
2:剪贴板的使用要引用WinForm
3: Excel是单线程的方式,所以代码里使用剪贴板也要用单线程的方式,[STAThread]。
4:在VS2013中调试状态下代码通过,可以将Excel中的图片取出并保存,在IIS下面报错。
Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80080005.
这个是一般的Excel报错,需要配置Excel组件,解决办法如下:Excel component set up open component services ,ComponentServices->Computers->DCOM Config-> Microsoft Excel Application
in Launch and Activation Permissionoption(add network service account give local launch and local activationpermission)
In Access Permission option (addnetwork service account give local access permission)
In Change Configuration Permissionoption give permission
(select the interactive user in identity)
if you can’t findMicrosoft Excel Application ,please new a folder named desktop</strong>:Create the Desktop folder, because Desktop folder seems to be necessary inthe systemprofile folder to open file by Excel</p><p>1).Windows 2008 Server x64 Please create
the folder: C:\Windows\SysWOW64\config\systemprofile\Desktop</p><p>2).Windows 2008 Server x86Please create this folder: C:\Windows\System32\config\systemprofile\Desktop
And give account Network Service write permission
下面是配置的截图:
5:最重要的一步是在IIS中网站对应的应用程序池的配置,也是整个项目的核心配置的地方,应用程序池要将Identity选择为LocalSystem.
这一点很关键,选择LocalSystem才能将excel中的图片复制到内存。
截图如下:
页面点击按钮事件:
目的:Asp.net web页面,读取Excel,(用的office组件),中的图片注意的事项:
只提供部分代码,因为重点是配置。
1:要想从Excel里读取图片,只能用剪贴板的方面将图片复制到内存然后再保存图片。
2:剪贴板的使用要引用WinForm
3: Excel是单线程的方式,所以代码里使用剪贴板也要用单线程的方式,[STAThread]。
4:在VS2013中调试状态下代码通过,可以将Excel中的图片取出并保存,在IIS下面报错。
Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80080005.
这个是一般的Excel报错,需要配置Excel组件,解决办法如下:Excel component set up open component services ,ComponentServices->Computers->DCOM Config-> Microsoft Excel Application
in Launch and Activation Permissionoption(add network service account give local launch and local activationpermission)
In Access Permission option (addnetwork service account give local access permission)
In Change Configuration Permissionoption give permission
(select the interactive user in identity)
if you can’t findMicrosoft Excel Application ,please new a folder named desktop</strong>:Create the Desktop folder, because Desktop folder seems to be necessary inthe systemprofile folder to open file by Excel</p><p>1).Windows 2008 Server x64 Please create
the folder: C:\Windows\SysWOW64\config\systemprofile\Desktop</p><p>2).Windows 2008 Server x86Please create this folder: C:\Windows\System32\config\systemprofile\Desktop
And give account Network Service write permission
下面是配置的截图:
5:最重要的一步是在IIS中网站对应的应用程序池的配置,也是整个项目的核心配置的地方,应用程序池要将Identity选择为LocalSystem.
这一点很关键,选择LocalSystem才能将excel中的图片复制到内存。
截图如下:
页面点击按钮事件:
//上传图片数据 protected void btnUploadPic_Click(object sender, EventArgs e) { try { div_result.InnerHtml = "Result area."; if (string.IsNullOrEmpty(fuUploadPic.FileName)) { div_result.InnerHtml = "Please Select A Excel File"; } else { m_UserID = UserInfo.User_ID.Value.ToString(); string ExcelName = fuUploadPic.FileName.Substring(fuUploadPic.FileName.LastIndexOf('.')); if (ExcelName != ".xls" && ExcelName != ".xlsx") { div_result.InnerHtml = "Please Select A Excel File"; return; } //保存上传文件到服务器 m_PictureExcelPath = Server.MapPath(System.Configuration.ConfigurationManager.AppSettings["MboardUploadFilePath"]) + Guid.NewGuid() + ExcelName; fuUploadPic.SaveAs(m_PictureExcelPath); string strSameNameArticleNo = ""; SameNameArticleNo(ref strSameNameArticleNo); m_SameNameArticleNo = strSameNameArticleNo; string IsRelativeOrAbsolute = System.Configuration.ConfigurationManager.AppSettings["IsRelativeOrAbsolute"]; if (IsRelativeOrAbsolute == null || IsRelativeOrAbsolute == "") m_PicPath = System.Configuration.ConfigurationManager.AppSettings["MboardUploadPicturePath_Absolute"]; else if (IsRelativeOrAbsolute == "1") m_PicPath = Server.MapPath(System.Configuration.ConfigurationManager.AppSettings["MboardUploadPicturePath_Relative"]); else if (IsRelativeOrAbsolute == "2") m_PicPath = System.Configuration.ConfigurationManager.AppSettings["MboardUploadPicturePath_Absolute"]; <span style="color:#ff0000;"> //提取Excel中图片存放到服务器指定路径 <strong><span style="font-size:18px;"> System.Threading.Thread cbThread = new System.Threading.Thread(new System.Threading.ThreadStart(UploadPicture)); cbThread.TrySetApartmentState(System.Threading.ApartmentState.STA);//指定单线程,否则无法从剪贴板中读取数据 cbThread.IsBackground = true; cbThread.Start(); while(cbThread.IsAlive) { System.Threading.Thread.Sleep(1000); }</span></strong></span> } } catch (Exception ex) { WriteErrorLog(ex); div_result.InnerHtml = ex.Message; } finally { //killExcel(); } } 单线程中的方法:
[STAThread] public void UploadPicture() { try { //初始化excel对象 Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application(); Microsoft.Office.Interop.Excel.Workbook workbook = null; try { string sql = ""; //打开xls文件(注意:后面的参数都用Type.Missing填充,表示使用参数的默认值) workbook = excel.Workbooks.Open(m_PictureExcelPath, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing, System.Type.Missing); if (workbook.Worksheets.Count > 0) { for (int i = 1; i <= workbook.Worksheets.Count; i++)//循环取所有的Sheet. { Microsoft.Office.Interop.Excel.Worksheet sheet = workbook.Worksheets.get_Item(i) as Microsoft.Office.Interop.Excel.Worksheet;//从1开始. string ArticleNoAll = ""; string ExcelArticleNoAll = ""; for (int row = 2; row <= sheet.UsedRange.Rows.Count; row++) { //选定图片名称到第n行第2列所在的单元格 string Article_No = ((Microsoft.Office.Interop.Excel.Range)sheet.Cells[row, 2]).Text.ToString().Trim().Replace(" ",""); if (Article_No.Length > 0) { ExcelArticleNoAll += "," + Article_No; string temExcelArticleNoAll = ExcelArticleNoAll + ","; string temExcelArticleNo = "," + Article_No + ","; int a = temExcelArticleNoAll.IndexOf(temExcelArticleNo); int b = temExcelArticleNoAll.LastIndexOf(temExcelArticleNo); if (temExcelArticleNoAll.IndexOf(temExcelArticleNo) == temExcelArticleNoAll.LastIndexOf(temExcelArticleNo)) { if (m_SameNameArticleNo.Contains(temExcelArticleNo) == false || (m_SameNameArticleNo.Contains(temExcelArticleNo) == true && cbReplaceSameName.Checked == true)) { //选定图片到第n行第1列所在的单元格 Microsoft.Office.Interop.Excel.Range r = (Microsoft.Office.Interop.Excel.Range)sheet.Cells[row, 1]; r.Select(); System.Windows.Forms.Clipboard.Clear(); //将单元格复制到剪贴板中 r.CopyPicture(Microsoft.Office.Interop.Excel.XlPictureAppearance.xlScreen, Microsoft.Office.Interop.Excel.XlCopyPictureFormat.xlBitmap); //string[] arrStr = System.Windows.Forms.Clipboard.GetDataObject().GetFormats(); System.Drawing.Image image = System.Windows.Forms.Clipboard.GetImage(); //判断剪贴板中是否存在图片,如果存在,则将图片存到指定目录中 //if (System.Windows.Forms.Clipboard.GetDataObject.ContainsImage()) if (image != null) { ArticleNoAll += ",'" + Article_No + "'"; string picPath = m_PicPath + Article_No + ".png"; image.Save(picPath, System.Drawing.Imaging.ImageFormat.Png);//保存到本地 int pic_height = image.Height; int pic_width = image.Width; sql += "INSERT INTO RMA_R_MBOARD_ARTICLE_PICTURE(Article_No,Picture_Path,OPERATE_USER,UPDATE_TIME,pic_height,pic_width) VALUES('" + Article_No + "','" + picPath + "'," + m_UserID + ",GETDATE()," + pic_height + "," + pic_width + ")" + "\n"; } } } } } if (ArticleNoAll != "" && ArticleNoAll.Length > 1) { ArticleNoAll = ArticleNoAll.Substring(1); sql = "DELETE FROM RMA_R_MBOARD_ARTICLE_PICTURE WHERE Article_No IN (" + ArticleNoAll + ")\n" + sql; int SecRowCount = sqlHelp.ExecuteNonQueryCmd(sql); if (SecRowCount > 0) { div_result.InnerHtml = "Upload Picture Successfully"; return; } else { div_result.InnerHtml = "Upload Picture Failed"; return; } //div_result.InnerHtml = "Upload Picture Successfully"; //return; } else { div_result.InnerHtml = "The picture already exists"; return; } } } else { div_result.InnerHtml = "Excel No Have Picture"; } workbook.Close(false, null, null); excel.Quit(); } catch (Exception ex) { workbook.Close(false, null, null); excel.Quit(); //WriteErrorLog(ex); div_result.InnerHtml = ex.Message; } finally { //System.Runtime.InteropServices.Marshal.ReleaseComObject(mysheet); //mysheet = null; //System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook); //workbook = null; //System.Runtime.InteropServices.Marshal.ReleaseComObject(myBooks); //myBooks = null; //System.Runtime.InteropServices.Marshal.ReleaseComObject(excel); //excel = null; workbook.Close(false, null, null); excel.Quit(); //KillExcelThread(excel); } } catch(Exception ex) { WriteErrorLog(ex); div_result.InnerHtml = ex.Message; } } 下面是Kill Excel的相关方法: private void killExcel() { //outPutEXCEL(); GC.Collect(); GC.WaitForPendingFinalizers(); } //获取句柄所对应的线程PID [System.Runtime.InteropServices.DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID); //Kill Excel 进程 private void KillExcelThread(Microsoft.Office.Interop.Excel.Application excel) { try { 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(Exception ex) { WriteErrorLog(ex); div_result.InnerHtml = ex.Message; } }
相关文章推荐
- Asp.NET 操作 Excel 组件时遇到“ System.UnauthorizedAccessException: 拒绝访问。”的解决办法
- ASP.Net中无法用javascript实现图片随屏幕移动的解决办法
- ASP.NET调用Oracle组件提示无法装载DLL(oci.dll)错误的解决办法
- ASP.Net中利用OLE读取Excel数据源时,报“未指定的错误”的错误解决办法
- (转)ASP.Net中无法用javascript实现图片随屏幕移动的解决办法
- ASP.Net中无法用javascript实现图片随屏幕移动的解决办法
- ASP.Net中无法用javascript实现图片随屏幕移动的解决办法
- 无法识别的属性“type”+IIS没有Asp.net配置选项的解决方法
- XP专业版中安装了IIS,配置好之后只能访问静态htm网页,图片之类的,但是ASP 文件确不能读取,提示无法显示网页提示
- Asp.Net 连接Oracle数据库 出现"找到 Oracle 客户端和网络组件" 的解决方法!(在win2003 ntfs 下IIS发布只显示登陆界面 不进入系统解决办法)
- 无法识别的属性“type”+IIS没有Asp.net配置选项的解决方法(转)
- asp.net配置IIS后"服务器应用程序不可用"的解决办法
- 无法识别的属性“type”+IIS没有Asp.net配置选项的解决方法
- 无法识别的属性“type”+IIS没有Asp.net配置选项的解决方法
- 无法识别的属性“type”+IIS没有Asp.net配置选项的解决方法
- ASP.NET 水晶报表在iis中无法显示的解决办法
- ASP.NET 水晶报表在iis中无法显示的解决办法
- ASP.NET 水晶报表在iis中无法显示的解决办法
- IIS打开asp.net 页面,无法找到该页,配置错误allowDefinition='MachineToApplication' 的节时错误解决方法。
- IIS7.5由于权限不足而无法读取配置文件的解决办法