最近项目中遇到的问题,网上找了很久这些问题的答案不是蛮多。所以现在整理出来。
1.二进制图片的转换
/// <summary>
/// 将图片转换为流
/// </summary>
/// <param name="url">图片的路径</param>
/// <returns>二进制图片数据流</returns>
public byte[] PicToStream(string url)
{
FileStream fs = new FileStream(url, FileMode.Open);//将图片写入流中。
int filelength = 0;
filelength = (int)fs.Length; //获得文件长度
Byte[] fl = new Byte[filelength]; //建立一个字节数组
fs.Read(fl, 0, filelength); //按字节流读取
fs.Close();
return fl;
}
/// <summary>
/// 参数是图片对象
/// </summary>
/// <param name="imgPhoto">图片对象</param>
/// <returns>二进制流</returns>
public byte[] PhotoImageInsert(System.Drawing.Image imgPhoto)
{
//将Image转换成流数据,并保存为byte[]
MemoryStream mstream = new MemoryStream();
imgPhoto.Save(mstream, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] byData = new Byte[mstream.Length];
mstream.Position = 0;
mstream.Read(byData, 0, byData.Length);
mstream.Close();
return byData;
}
/// <summary>
/// 参数是byte返回图片
/// </summary>
/// <param name="streamByte">二进制数据流</param>
/// <returns>图片</returns>
public System.Drawing.Image ReturnPhoto(byte[] streamByte)
{
MemoryStream ms = new MemoryStream(streamByte);
Image img = Image.FromStream(ms);
ms.Close();
return img;
}
/// <summary>
/// 创建图片文件
/// </summary>
/// <param name="bytes">图片的数据流</param>
/// <param name="ID">图片的id号</param>
/// <returns>图片名称</returns>
public string CreatPic (byte[] bytes,string ID)
{
byte[] buffer = bytes;//把文件流转化成字节数组
int buffersize = (int)bytes.Length;//获取流的长度
string dt = DateTime.Now.ToString("yyyyMMddHHmmss");//取当前时间戳作为新文件名
string picNewName = ID + dt;//图片的id号和当前时间一起命名为图片的名称。
string serverpath = System.Windows.Forms.Application.StartupPath + "\\PhotoFiles\\" + picNewName + ".jpg";//文件保存路径
FileStream fs = new FileStream(serverpath, FileMode.Create, FileAccess.Write);//创建文件
fs.Write(buffer, 0, buffersize);//写入数据
fs.Flush();//清出缓冲区
fs.Close();//关闭流
return picNewName;
}
2.将二进制图片存入excel表格中(存进去的是图片)
首先要引用EXCEL.dll或Interop.Excel
然后用的时候我实例化这些对象
Excel.Application myExcel = new Excel.Application();
Excel.Workbook xlBook;
Excel.Worksheet xlSheet;
Excel.Range xlsRange;
// filepath为你的excel文件的路径。
xlBook = (Excel.Workbook)myExcel.Workbooks.Open(@"" + filepath + "", Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
xlSheet = (Excel.Worksheet)xlBook.Worksheets[1]; //设置为操作当前的第一张表sheet1,这个可以设置的。以为一个excel中可以有多张表。
----------------------------现在可以操作excel了--------------------------------------------- Image bmp = ReturnPhoto(Bytes);//Bytes为你要插入图片的二进制数据流
//复制到粘贴板
System.Windows.Forms.Clipboard.SetDataObject(bmp, true);
xlsRange = workSheet.get_Range((Excel.Range)workSheet.Cells[x, y],(Excel.Range)workSheet.Cells[x, y]);
app.get_Range((Excel.Range)app.Cells[x, y], (Excel.Range)app.Cells[x, y]).ColumnWidth = 60;
app.get_Range((Excel.Range)app.Cells[x, y], (Excel.Range)app.Cells[x, y]).RowHeight = 80;
//粘贴到excel中的指定的单元格里----x为excel单元格的行,y为excel单元格的列(就是要填入图片对应的单元格的坐标)
workSheet.Paste(xlsRange, bmp);
--------------------------------操作成功开始关闭----------------------------------------------
//关闭excel资源
workBook.Close(null, null, null);
myExcel.Workbooks.Close();
myExcel.Quit();
if (xlsRange != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsRange );
xlsRange = null;
}
if (xlSheet != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet);
xlSheet = null;
}
if (xlBook != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook);
xlBook = null;
}
if (myExcel != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(myExcel);
myExcel = null;
}
GC.Collect();
Process[] myProcesses;
myProcesses = Process.GetProcessesByName("Excel");
//结束所有excel进程
foreach (Process myProcess in myProcesses)
{
//杀掉所有进程
myProcess.Kill();
}
-------------------------------完成----------------------------------------------
3.将excel中的图片读出来写入数据库
前面的实例化和上面是一样的.
Excel.Shapes shapes = xlSheet.Shapes;
for (int i = 1; i < shapes.Count + 1; i++)
{
shapes.Item(i).CopyPicture(Appearance.Button,Excel.XlCopyPictureFormat.xlBitmap);
IDataObject objIDO = (IDataObject)Clipboard.GetDataObject();
if (objIDO.GetDataPresent(DataFormats.Bitmap))
{
Image img = (Bitmap)objIDO.GetData(DataFormats.Bitmap);
img.Save(Application.StartupPath + "\\TempPhoto\\" + i + ".jpg");
}
}
这样就可以把读出来的图片放进一个文件夹中了。因为中间有可能没有图片的信息。这样图片的顺序和信息的顺序就对应不上了。我的解决方案就是将图片按顺序的名称放进一个临时文件夹。然后在按照索引读取excel 的信息的时候读到图片的信息的时候判断是不是为空,不为空就打开临时文件夹按顺序添加图片。图片的索引是1开始,我们可以在读取excel信息的时候在循环的外面赋一个变量值为1,然后每次循环(里面)的结尾然后变量加1,这样的话就可以对应了。