您的位置:首页 > 编程语言 > ASP

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中的图片复制到内存。


截图如下:



页面点击按钮事件:

//上传图片数据
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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐