動態匯出Word檔第二篇,匯出圖片
既昨天發的那篇不靠GridView,動態匯出Word檔
今天來試驗能不能動態的匯出圖片。
不過我試了一下,發現太簡單了,所以又做了一些變化。
總之,還是先貼個圖片到word中,存成xml檔,再開起來看他是怎麼存的
原始檔
*小技巧*
可以用WinMerge這個軟體來比對有圖檔跟沒有圖檔的xml的差異,而且很佛心的有中文語系。
可以很清楚的看到,右邊那個tag下多出來的一大串鬼畫符,就是圖片的二進位碼。
另外在檔案的上方還有圖檔對應的名稱,跟圖片的設定格式
知道基本的規則後,剩下的就跟昨天一樣啦,先把那坨鬼畫符用自己設的字串替代掉
然後等等用程式讀這支Xml檔,再用replace把自訂字串換成另一張圖片的二進位碼,就完成了。
簡單的圖檔轉二進位
Image image = Image.FromStream(圖檔路徑);
image.Save(ms,ImageFormat.Jpeg);
//將MemoryStream轉成字串
string picBase64 =
Convert.ToBase64String(ms.GetBuffer(), Base64FormattingOptions.InsertLineBreaks);
上面這段很簡單,但如果沒設定Base64FormattingOptions.InsertLineBreaks的話
匯出去的檔案會開不起來。
詳情請看MSDN的說明Base64FormattingOptions 列舉型別
接著做法都跟昨天一樣,所以就不再重複了。
但我又做了一點小變化,讓圖檔可以從URL上抓過來,Code如下
public ActionResult ExportPic(string path)
{
//建立HttpWebRequest,傳入網址,再利用GetResponse得到HttpWebResponse
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(path);
HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse();
//轉為串流
Stream dataStream = httpResponse.GetResponseStream();
//因為我在試Stream轉byte[]時遇到些問題,所以先用笨方法
//先將串流轉成Image,在利用上面的方法讀
Image image = Image.FromStream(dataStream);
MemoryStream ms = new MemoryStream();
image.Save(ms, ImageFormat.Jpeg);
httpResponse.Close();
dataStream.Dispose();
image.Dispose();
//下面都跟昨天差不多
Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=test.doc");//word檔名
Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
Response.ContentType = "application/vnd.ms-word";
Response.Charset = "";
string myXML = "";
StreamReader srXML = new StreamReader(Server.MapPath("~/App_Data/ExportImage.xml"));
myXML = srXML.ReadToEnd();
srXML.Close();
//將Memory轉為byte[]再轉為字串
string picBase64 = Convert.ToBase64String(ms.GetBuffer(), Base64FormattingOptions.InsertLineBreaks);
//替換
myXML = myXML.Replace("!MyImage!", picBase64);
Response.Write(myXML);
Response.End();
return View();
}
View
{ %>
<input type="text" name="path" style="width:400px;" />
<input type="submit" value="送出"/>
<%} %>
直接來看執行的結果吧
送出之後,會跳出儲存檔案的對話框
存檔之後看word檔裡面有什麼
(個人偏好美女圖...)
這樣就完成可以利用圖片的網址,將圖塞到word裡面存成檔案啦。
另外我的問題是
原來想直接用Stream寫到byte[]裡面的,像下面這樣
byte[] b=new byte[dataStream.Length];
while (dataStream.Read(b, 0, b.Length) > 0)
{
}
但卻會出現這個錯誤
如果我先給定byte[]的長度
會變成有些圖片可以讀成功,有些會破圖。
還沒想到是什麼問題,而且我愛睏了....知道原因的麻煩分享一下吧。
參考資料: