ReportViewer自己寫列印報表按鈕

Designed by Freepik
其實ReportViewer裡面已經內建有列印功能了,
但是因為IE版本的不同,或是使用者使用Chrome等其他瀏覽器,
這顆列印的按鈕會羞於見人。。。
我就遇到了,那只好自己動手寫Print按鈕啦。
其實就是在Server端產生PDF檔,然後下載列印而已。
缺點就是,Server上的PDF檔,得另外清理了。
圖片來源Designed by Freepik


  1. 我們得準備將報表產生為PDF檔的function
private string CreateFile(string szFileType, string szfilename)
{
    string sMSG = "";
    Warning[] warnings;
    string[] streamids;
    string mimeType;
    string encoding = "utf-8";

    string extension;
    try
    {
        byte[] bytes = this.ReportViewer1.LocalReport.Render(szFileType.ToUpper(), null, out mimeType,
           out encoding, out extension, out streamids, out warnings);
        FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(szfilename), FileMode.Create);
        fs.Write(bytes, 0, bytes.Length);
        fs.Close();
        fs.Dispose();
    }
    catch (Exception ex)
    {
        sMSG = ex.Message.ToString();
    }
    return sMSG;
}

  1. 接著將PDF下載,並呼叫列印視窗
protected void btnPrint_Click(object sender, EventArgs e)
{
    string sOutPutFile, sPrintFile;
    sOutPutFile = @"~/temp/output_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";
    sPrintFile = @"~/temp/Print_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";
    CreateFile("PDF", sOutPutFile);

    //Open existing PDF
    Document document = new Document(PageSize.A4);
    PdfReader reader = new PdfReader(HttpContext.Current.Server.MapPath(sOutPutFile));

    //Getting a instance of new PDF writer
    PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(HttpContext.Current.Server.MapPath(sPrintFile), FileMode.Create));
    document.Open();
    PdfContentByte cb = writer.DirectContent;

    int i = 0;
    int p = 0;
    int n = reader.NumberOfPages;
    Rectangle psize = reader.GetPageSize(1);

    float width = psize.Width;
    float height = psize.Height;

    //Add Page to new document
    while (i < n)
    {
        document.NewPage();
        p++;
        i++;

        PdfImportedPage page1 = writer.GetImportedPage(reader, i);
        cb.AddTemplate(page1, 0, 0);
    }

    //Attach javascript to the document
    PdfAction jAction = PdfAction.JavaScript("this.print(true);\r", writer);
    writer.AddJavaScript(jAction);
    document.Close();

    //Attach pdf to the iframe
    frmPrint.Attributes["src"] = sPrintFile;
}

就這樣~ 上述的方法目前遇到的問題是,Server上最新一筆的PDF檔的IO會被鎖定。 沒辦法刪除。 另外Chrome似乎會彈出兩次列印視窗。 有空的時候再研究好囉。

沒有留言:

張貼留言

技術提供:Blogger.