動態匯出Word檔第二篇,匯出圖片

動態匯出Word檔第二篇,匯出圖片

既昨天發的那篇不靠GridView,動態匯出Word檔

今天來試驗能不能動態的匯出圖片。

不過我試了一下,發現太簡單了,所以又做了一些變化。

總之,還是先貼個圖片到word中,存成xml檔,再開起來看他是怎麼存的

原始檔

a0e30318be48417a8591b96b6f7c80d3

*小技巧*

可以用WinMerge這個軟體來比對有圖檔跟沒有圖檔的xml的差異,而且很佛心的有中文語系。

3846ddd2458444eb8d1599d971671e74

可以很清楚的看到,右邊那個tag下多出來的一大串鬼畫符,就是圖片的二進位碼。

另外在檔案的上方還有圖檔對應的名稱,跟圖片的設定格式

feda1d67827f4afb9002d31f17a4ff7f

知道基本的規則後,剩下的就跟昨天一樣啦,先把那坨鬼畫符用自己設的字串替代掉

然後等等用程式讀這支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="送出"/>
<%} %>

直接來看執行的結果吧

8842405d7d3240f49ee9a965402adb8b

送出之後,會跳出儲存檔案的對話框

a4654ba18e44410e87b1b2847f7ae71d

存檔之後看word檔裡面有什麼

db17120062ae4ef7b2ecdf2c2ae0fcbc

(個人偏好美女圖...)

這樣就完成可以利用圖片的網址,將圖塞到word裡面存成檔案啦。

另外我的問題是

原來想直接用Stream寫到byte[]裡面的,像下面這樣



byte[] b=new byte[dataStream.Length];

while (dataStream.Read(b, 0, b.Length) > 0)
{
}

但卻會出現這個錯誤

48f6b125a3cc4e438cef67db668bd702

如果我先給定byte[]的長度

會變成有些圖片可以讀成功,有些會破圖。

還沒想到是什麼問題,而且我愛睏了....知道原因的麻煩分享一下吧。

 

參考資料:

黑大-CODE-使用C#程式從網站下載檔案