0

以下のコードで wkhtmltopdf.exe を使用して PDF を生成しています。

 string url = HttpContext.Current.Request.Url.AbsoluteUri;

        //string[] strarry = sPath.Split('/');
        //int lengh = strarry.Length;

  var pdfUrl = HtmlToPdf(pdfOutputLocation: "~/PDF/", outputFilenamePrefix: "DT", urls: new string[] { url });

        WebClient req = new WebClient();
        HttpResponse response = HttpContext.Current.Response;
        response.Clear();
        response.ClearContent();
        response.ClearHeaders();
        response.Buffer = true;
        Response.ContentType = "application/pdf";
        response.AddHeader("Content-Disposition", "attachment;filename=\"" + pdfUrl.ToString().Substring(6) + "\"");
        byte[] data = req.DownloadData(Server.MapPath(pdfUrl.ToString()));
        response.BinaryWrite(data);
        File.Delete(Server.MapPath(pdfUrl.ToString()));
        response.End();

  public static string HtmlToPdf(string pdfOutputLocation, string outputFilenamePrefix, string[] urls,
 string[] options = null,
 string pdfHtmlToPdfExePath = "C:\\Program Files\\wkhtmltopdf\\wkhtmltopdf.exe")
    {
        string urlsSeparatedBySpaces = string.Empty;
        try
        {
            //Determine inputs
            if ((urls == null) || (urls.Length == 0))
                throw new Exception("No input URLs provided for HtmlToPdf");
            else
                urlsSeparatedBySpaces = String.Join(" ", urls); //Concatenate URLs

            string outputFolder = pdfOutputLocation;
            string outputFilename = outputFilenamePrefix + "_" + DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss-fff") + ".PDF"; // assemble destination PDF file name

            var p = new System.Diagnostics.Process()
            {
                StartInfo =
                {
                    FileName = pdfHtmlToPdfExePath,
                    Arguments = ((options == null) ? "" : String.Join(" ", options)) + " " + urlsSeparatedBySpaces + " " + outputFilename,
                    UseShellExecute = false, // needs to be false in order to redirect output
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    RedirectStandardInput = true, // redirect all 3, as it should be all 3 or none
                    WorkingDirectory = HttpContext.Current.Server.MapPath(outputFolder)
                }
            };

            p.Start();

            // read the output here...
            var output = p.StandardOutput.ReadToEnd();
            var errorOutput = p.StandardError.ReadToEnd();

            // ...then wait n milliseconds for exit (as after exit, it can't read the output)
            p.WaitForExit(60000);

            // read the exit code, close process
            int returnCode = p.ExitCode;
            p.Close();

            // if 0 or 2, it worked so return path of pdf
            if ((returnCode == 0) || (returnCode == 2))
                return outputFolder + outputFilename;
            else
                throw new Exception(errorOutput);



            //Response.ContentType = "application/pdf";
            //Response.AddHeader("content-length", theData.Length.ToString());
            //if (Request.QueryString["attachment"] != null)
            //    Response.AddHeader("content-disposition", "attachment; filename=ExampleSite.pdf");
            //else
            //    Response.AddHeader("content-disposition", "inline; filename=ExampleSite.pdf");
            //Response.BinaryWrite(theData);
            //HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
        catch (Exception exc)
        {
            throw new Exception("Problem generating PDF from HTML, URLs: " + urlsSeparatedBySpaces + ", outputFilename: " + outputFilenamePrefix, exc);
        }
    }

上記のコードから、PDF は適切に生成されています。しかし、ログイン ユーザーとログアウト ユーザーに同じ URL を持つ 2 つのページがあります。たとえば、www.xyz/pdf/brason とします。ユーザーのログインまたはログアウトによって異なります。

ログインして上記のコードを使用して PDF を生成しようとすると、ログアウト ユーザー ページのコンテンツが常に表示されます。この問題をどのように解決できるかわかりません。

4

2 に答える 2

1

私が正しく理解していれば、これはページを呼び出している wkhtmltopdf がログインしていないためだと思います。 wkhtmltopdf が呼び出されたときにサーバーが取得する要求をデバッグして確認します。

これが問題である場合、解決するのは難しい場合があります。解決策は、ログイン システムと、問題を回避するために何ができるかによって異なります。Cookie を使用してログインを複製できる場合は、ログイン Cookie を自分で設定することもできますクッキーの設定方法。

別のオプションは、最初にログインした HTML を返すシステムからリクエストを作成し、それをファイル/ストリームに保存し、そのファイル/ストリームを wkhtmltopdf にフィードすることです (HttpContext.Current.Request を使用してそれを行うことができると思います)。か何か、私は知りません)。

もう 1 つの回避策は、ログイン ページとまったく同じように見えるが、実際にはそうではない、ログイン ページの複製ページを作成することです。このページは、wkhtmltopdf を騙すために使用されます。のようなwww.xyz/pdf/brason?foolwkhtmltopdf=trueものを呼び出して、それを使用しif(url.ToLower() == "www.xyz/pdf/brason") {url="www.xyz/pdf/brason?foolwkhtmltopdf=true"; }ます。ただし、表示される情報によっては、これがセキュリティ リスクになる可能性があります。

お役に立てれば!

于 2013-01-13T12:13:27.567 に答える
0

html に変換する前に、ページの出力を保存する必要があると思います。これはURLを直接呼び出し、要求に対して取得した応答をpdfに変換するときにサインインしていないため、Webフォームをpdfに変換しようとして同じ問題が発生しましたが、値が入力されたため、応答をhtmlとして保存し、与えられた wkhtmltopdf パラメータとして保存されたパス

 Response.ContentType = "application/pdf";
        Response.AddHeader("content-disposition", "attachment;filename=TestPage.pdf");
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        StringWriter sw = new StringWriter();
        HtmlTextWriter hw = new HtmlTextWriter(sw);
        this.Page.RenderControl(hw);
        StringReader sr = new StringReader(sw.ToString());
        string htmlpath =Server.MapPath("~/htmloutput.html");
        if (File.Exists(htmlpath))
        {
            File.Delete(htmlpath);

        }  

        File.Create(htmlpath).Dispose();
        using (TextWriter tw = new StreamWriter(htmlpath))
        {
            tw.WriteLine(sw.ToString());
            tw.Close();
        }

        string path = Server.MapPath("~/wkhtmltopdf-page.pdf");
        PdfConvert.ConvertHtmlToPdf(new Codaxy.WkHtmlToPdf.PdfDocument
        {
            Url = htmlpath,
            HeaderLeft = "[title]",
            HeaderRight = "[date] [time]",
            FooterCenter = "Page [page] of [topage]"

        }, new PdfOutput
        {

            OutputFilePath = path

        });

ボタンクリックイベントでこれを呼び出すことができます。これは、asp.net Webフォームでのみテストされています。asp.net mvc では、ビューの html 出力を取得する別の方法が必要です

于 2015-12-18T10:46:15.050 に答える