Asp.net 从Excel读取图片并保存,无法从内存读取图片,Excel组件和相关IIS的配置及解决办法

</pre>目的:Asp.net web页面,读取Excel,(用的office组件),中的图片注意的事项:<p></p><p>只提供部分代码,因为重点是配置。</p><p>1:要想从Excel里读取图片,只能用剪贴板的方面将图片复制到内存然后再保存图片。</p><p>2:剪贴板的使用要引用WinForm</p><p>3: Excel是单线程的方式,所以代码里使用剪贴板也要用单线程的方式,[STAThread]。</p><p>4:在VS2013中调试状态下代码通过,可以将Excel中的图片取出并保存,在IIS下面报错。</p><p>Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80080005. </p><p>这个是一般的Excel报错,需要配置Excel组件,解决办法如下:</p><p></p><p> Excel component set up     open component services ,ComponentServices->Computers->DCOM Config-> Microsoft Excel Application</p><p>in Launch and Activation Permissionoption(add network service account give local launch and local activationpermission)</p><p>In Access Permission option (addnetwork service account give local access permission)</p><p>In Change Configuration Permissionoption give permission</p><p>(select the interactive user in identity)</p><p><img src="http://img.blog.csdn.net/20150515110853044?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmRkcWZkZHE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /><img src="http://img.blog.csdn.net/20150515110953483?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmRkcWZkZHE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /><img src="http://img.blog.csdn.net/20150515110911655?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmRkcWZkZHE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /><img src="http://img.blog.csdn.net/20150515111004293?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmRkcWZkZHE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /><img src="http://img.blog.csdn.net/20150515111012483?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmRkcWZkZHE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /><img src="http://img.blog.csdn.net/20150515110930141?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmRkcWZkZHE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></p><p><strong>if you can’t findMicrosoft Excel Application ,please new a folder named desktop</strong>:</p><p>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 x86</p><p>  Please create this folder: C:\Windows\System32\config\systemprofile\Desktop   </p><p>And give account <span style="color:#333333; background:whitesmoke">Network Service write permission</span></p> 5:<strong><span style="font-size:18px; color:#ff0000">最重要的一步是在IIS中网站对应的应用程序池的配置,也是整个项目的核心配置的地方,应用程序池要将Identity选择为LocalSystem.</span></strong><p><strong><span style="font-size:18px; color:#ff0000">     这一点很关键,选择LocalSystem才能将excel中的图片复制到内存。</span></strong></p><p><img src="http://img.blog.csdn.net/20150515113821385?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmRkcWZkZHE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></p><p></p><p></p><p>WebForm</p><p></p><p></p><p> 页面点击按钮事件:</p><pre code_snippet_id="667270" snippet_file_name="blog_20150515_2_7423722" name="code" class="csharp"> //上传图片数据
        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();
            }
        }

单线程中的方法:

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;
            }
        }



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。