在EXCEL中插入内存中的图片(VSTO)

    Excel中一般是通过Worksheet.Shapes.AddPicture方法添加图片,方法的参数格式为:
    AddPicture([In] string Filename,    [In] MsoTriState LinkToFile,    [In] MsoTriState SaveWithDocument,    [In] float Left,    [In] float Top,    [In] float Width,    [In] float Height);
    其中Filename必须是一个uri路径,内存中的图片对象则没有办法使用此方法插入。
    我们的项目是一个SmartClient的VSTO项目,当时总有一个意识在支配我,那就是尽可能不要访问本地资源,而如果内存中的图片不写到本地又该如何插入到EXCEL中呢?Google吧,结果搜到一个连他自己都说“Heavyweight”的解决方案,那就是在本地临时创建一个最小型的HTTP Server,将内存中的图片数据交给它,然后由它再展交给AddPicture,代码如下:
None.gif using  System;
None.gif
using  System.IO;
None.gif
using  System.Net;
None.gif
using  System.Net.Sockets;
None.gif
using  System.Text;
None.gif
using  System.Threading;
None.gif
None.gif
namespace  YourNameSpace
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public class LocalWebServer:IDisposable
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private TcpListener myListener;
InBlock.gif        
private static readonly Guid terminationGuid = new Guid("{7b0d9a9d-fbec-4fe5-8ea7-fc3b313510fc}");
InBlock.gif        
byte[] contentsToServe;
InBlock.gif        Thread thread;
InBlock.gif        
string fileName;
InBlock.gif        
int myPort;
InBlock.gif
InBlock.gif        
//The constructor which makee the TcpListener start listening on the
InBlock.gif        
//given port. It also creates a Thread on the method StartListen(). 
InBlock.gif

InBlock.gif        
public LocalWebServer(int port, string fileName, byte[] contents)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//start listing on the given port
InBlock.gif
                myListener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
InBlock.gif                contentsToServe 
= contents;
InBlock.gif                
this.fileName = fileName;
InBlock.gif                
this.myPort = port;
InBlock.gif
InBlock.gif                myListener.Start();
InBlock.gif                System.Diagnostics.Debug.WriteLine(
"Web Server Runningdot.gif Press ^C to Stopdot.gif");
InBlock.gif
InBlock.gif                
//start the thread which calls the method 'StartListen'
InBlock.gif
                Thread th = new Thread(new ThreadStart(StartListen));
InBlock.gif                
this.thread = th;
InBlock.gif                th.Start();
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.Diagnostics.Debug.WriteLine(
"An Exception Occurred while Listening :" + e.ToString());
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void SendHeader(string sHttpVersion, string sMIMEHeader, int iTotBytes, string sStatusCode, TcpClient tcpClient)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            StringBuilder sBuffer 
= new StringBuilder();
InBlock.gif            
// if Mime type is not provided set default to text/html
InBlock.gif

InBlock.gif            
if (string.IsNullOrEmpty(sMIMEHeader))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                sMIMEHeader 
= "text/xml";  // Default Mime Type is text/xml
ExpandedSubBlockEnd.gif
            }

InBlock.gif
InBlock.gif            sBuffer.Append(sHttpVersion);
InBlock.gif            sBuffer.AppendLine(sStatusCode);
InBlock.gif            sBuffer.AppendLine(
"Server: VSTOServer");
InBlock.gif            sBuffer.Append(
"Content-Type: ");
InBlock.gif            sBuffer.AppendLine(sMIMEHeader);
InBlock.gif            sBuffer.AppendLine(
"Accept-Ranges: bytes");
InBlock.gif            sBuffer.Append(
"Content-Length: ");
InBlock.gif            sBuffer.AppendLine(iTotBytes.ToString());
InBlock.gif            sBuffer.AppendLine(
"");
InBlock.gif
InBlock.gif            Byte[] bSendData 
= Encoding.ASCII.GetBytes(sBuffer.ToString());
InBlock.gif            SendToBrowser(bSendData, tcpClient);
InBlock.gif            System.Diagnostics.Debug.WriteLine(
"Total Bytes : " + iTotBytes.ToString());
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void SendToBrowser(Byte[] bSendData, TcpClient tcpClient)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (tcpClient.Connected)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    NetworkStream stream 
= tcpClient.GetStream();
InBlock.gif                    stream.Write(bSendData, 
0, bSendData.Length);
InBlock.gif                    stream.Flush();
ExpandedSubBlockEnd.gif                }

InBlock.gif                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    System.Diagnostics.Debug.WriteLine(
"Connection Droppeddot.gif.");
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.Diagnostics.Debug.WriteLine(String.Format(
"Error Occurred : {0} ", e));
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void StartListen()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            
int iStartPos = 0;
InBlock.gif            String sErrorMessage;
InBlock.gif            
while (true)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//Accept a new connection
InBlock.gif
                using (TcpClient tcpClient = myListener.AcceptTcpClient())
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if (tcpClient.Connected)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        System.Diagnostics.Debug.WriteLine(String.Format(
"\nClient Connected!!\n==================\nClient IP {0}\n", tcpClient.Client.RemoteEndPoint));
InBlock.gif                        NetworkStream stream 
= tcpClient.GetStream();
InBlock.gif                        
//make a byte array and receive data from the client 
InBlock.gif
                        Byte[] bReceive = new Byte[1024];
InBlock.gif                        
int i = stream.Read(bReceive, 0, bReceive.Length);
InBlock.gif                        
//Convert Byte to String
InBlock.gif
                        string sBuffer = Encoding.ASCII.GetString(bReceive);
InBlock.gif                        
// Look for HTTP request
InBlock.gif
                        iStartPos = sBuffer.IndexOf("HTTP"1);
InBlock.gif                        
// Get the HTTP text and version e.g. it will return "HTTP/1.1"
InBlock.gif
                        string sHttpVersion = sBuffer.Substring(iStartPos, 8);
InBlock.gif                        
//At present we will only deal with GET type
InBlock.gif                        
// if OPTION received, still OK
InBlock.gif
                        if (!sBuffer.StartsWith("GET"))
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            System.Diagnostics.Debug.WriteLine(
"Only Get Method is supported..");
InBlock.gif                            SendHeader(sHttpVersion, 
null0" 501 Not Implemented", tcpClient);
InBlock.gif                            
continue;
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
if (sBuffer.Contains(terminationGuid.ToString()))
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            SendHeader(sHttpVersion, 
null0" 200 OK", tcpClient);
InBlock.gif                            
break;
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
if (!sBuffer.Contains(fileName))
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            sErrorMessage 
= "<H2>404 Error! File Does Not Existdot.gif</H2>";
InBlock.gif                            SendHeader(sHttpVersion, 
"", sErrorMessage.Length, " 404 Not Found", tcpClient);
InBlock.gif                            SendToBrowser(Encoding.ASCII.GetBytes(sErrorMessage), tcpClient);
InBlock.gif                            
continue;
ExpandedSubBlockEnd.gif                        }

InBlock.gif
InBlock.gif                        SendHeader(sHttpVersion, 
null, contentsToServe.Length, " 200 OK", tcpClient);
InBlock.gif                        SendToBrowser(contentsToServe, tcpClient);
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            myListener.Stop();
ExpandedSubBlockEnd.gif        }

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
IDisposable Members#region IDisposable Members
InBlock.gif        
public void Dispose()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// Send a termination request to stop the web server
InBlock.gif
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:" + myPort + "/" + terminationGuid.ToString());
InBlock.gif            WebResponse response 
= request.GetResponse();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
    调用时可以使用这个方法:
None.gif          private   void  AddPictureByWeb(Excel.Worksheet worksheet,  string  fileName,  byte [] contents,  float  left,  float  top,  float  width,  float  height)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
// Use any private port in the range 49152–65535
InBlock.gif
            int portNumber = 50213;
InBlock.gif            fileName 
= System.Web.HttpUtility.UrlEncode(fileName);
InBlock.gif            
using (new LocalWebServer(portNumber, fileName, contents))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
// the request will land with the WebServer object in this process
InBlock.gif
                string url = @"http://localhost:" + portNumber + "/" + fileName;
InBlock.gif                worksheet.Shapes.AddPicture(url, Office.MsoTriState.msoFalse, Office.MsoTriState.msoTrue,
InBlock.gif                                   left, top, width, height);
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

None.gif
    内存的图片数据交给byte[] contents即可。
    当这个方案成功后,我却突然开了窍,既然是VSTO的项目,一般来说需要客户端FullTrust许可,那么写到本地临时目录中根本不成问题呀,何苦如此大动干戈呢?于是:
None.gif dot.gif.
None.gifBitmap image 
=   new  Bitmap( new  MemoryStream(buffer))
None.gifimage.Save(filePath, ImageFormat.Jpeg);
None.gifworksheet.Shapes.AddPicture(filePath, Office.MsoTriState.msoFalse,  Office.MsoTriState.msoTrue, left, top, width, height);
None.gifFile.Delete(filePath);
None.gifdot.gif.

转载于:https://www.cnblogs.com/dotAge/archive/2006/09/14/494790.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值