我在「將網頁整個封存為 .mht 單一檔案」一文中介紹過 IE 可以將整個網頁儲存為單一網頁。但是有沒有可能撰寫程式,主動提供使用者將網頁的一部份儲存為 .mht 檔案呢...
我在「將網頁整個封存為 .mht 單一檔案」一文中介紹過 IE 可以將整個網頁儲存為單一網頁。但是有沒有可能撰寫程式,主動提供使用者將網頁的一部份儲存為 .mht 檔案呢?這裡我要強調將「網頁的一部份」儲存為 .mht 而不是將「整個網頁」儲存,因為後者使用 IE 就可以輕易辦到了。
的確是有辦法的。請參考 CodeProject 的這個主題:Convert HTML to MHTML using ASP.NET(你可能被要求註冊並登入)。
要使用這個 Solution,你有幾件事情要做。首先,你必須將 cdosys.dll 這個檔案加入網站專案的參考。請在網站專案上按滑鼠右鍵,選擇「加入參考」,然後選 COM 這個標簽,再挑選「Microsoft CDO for Windows 2000 Library」,再按確定即可。加入之後,你將在專案的 Bin 資料夾裡面發現 Interop ADODB.dll 和 Interop.CDO.dll 兩個檔案。
其次,回到上述 Code Project 網站,把它的原始檔下載下來。解開壓縮,放置在任意資料夾。
你可以在原始檔案中找到以下三個關鍵檔案:
- mht.vb
- mhtImage.vb
- mhtImageCollection.vb
請將這三個 VB 檔案拷貝到網站裡面的 App_Code 資料夾裡面。其實這三個檔案可以組合成一個檔案,不過這並不重要。
請打開 mht.vb,把 sendMHTFile() 程序改成如下的樣子:
'Send a mhtml string as a mhtml Word document to the client
Public Sub sendMHTFile(ByVal target As Page, ByVal MHTString As String, ByVal fileName As String)
target.Response.Clear()
target.Response.ClearContent()
target.Response.ClearHeaders()
target.Response.ContentType = "application/msword"
target.Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName)
target.Response.Write(MHTString)
target.Response.Flush()
target.Response.Close()
End Sub
我想作者會寫成原來的樣子,一定是因為發現如果寫成 Class Library,無法使用 Response。不過如果像我改成那個樣子,Response 就可以正常使用了;這算是一個很多人都不知道的小技巧。
接下來,你可以參考原始檔案中的 WebForm1.aspx 當作範例。不過我已經把它改過了,其程式碼如下:
Dim mht As New mht
Private Sub ButtonConvert_Click(...) Handles ButtonConvert.Click
Dim oMhtCol As New mhtImageCollection
oMhtCol.add(New mhtImage(System.Drawing.Image.FromFile(Server.MapPath("~/Images/myComputer.jpg")), "../Images/myComputer.jpg", System.Drawing.Imaging.ImageFormat.Jpeg))
mht.sendMHTFile(Me, mht.convertWebControlToMHTString(Panel1, oMhtCol), "myFirstMht.mht")
End Sub
請將原始檔案中的 Images/myComputer.jpg 拷目到你的網站中的 Images/myComputer.jpg。現在你可以開始測試了。
這個 Solution 絕非完美。經我測試,它並無法辨識網頁中的樣式設定。你可以把作者的程式加以修改,或是你可以強制 Panel1 中的個別控制項都指定樣式。不過不管如何,你現在已經多了一個工具,可以指定一個 Panel 物件,先把資料放進這個 Panel 中,再加上一個按鈕讓客戶下載其內容了。