從 ASP.NET 程式中將 Container 物件轉換為 .mht 格式以供下載

我在「將網頁整個封存為 .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 中,再加上一個按鈕讓客戶下載其內容了。


Dev 2Share @ 點部落