5

私はabcPdfを使用してHTMLレポートをPDFファイルに変換しています。PDFは単一の横向きのA4ページである必要があります。

PDFの単一ページに収まるようにHTMLページを拡大縮小するようにabcPdfに指示する方法があるかどうか知っていますか?Magnify()メソッドを使用してみましたが、コンテンツを拡大縮小しますが、1ページに収まる場合でも、ページに分割します。私はしばらくの間これに頭を悩ませてきました、そして誰かがそれをしたかどうか疑問に思っています。

現在使用しているコードは次のとおりです。

public byte[] UrlToPdf(string url, PageOrientation po)
{
    using (Doc theDoc = new Doc())
    {
        // When in landscape mode:
        // We use two transforms to apply a generic 90 degree rotation around
        // the center of the document and rotate the drawing rectangle by the same amount.
        if (po == PageOrientation.Landscape)
        {
            // apply a rotation transform
            double w = theDoc.MediaBox.Width;
            double h = theDoc.MediaBox.Height;
            double l = theDoc.MediaBox.Left;
            double b = theDoc.MediaBox.Bottom;
            theDoc.Transform.Rotate(90, l, b);
            theDoc.Transform.Translate(w, 0);

            // rotate our rectangle
            theDoc.Rect.Width = h;
            theDoc.Rect.Height = w;

            // To change the default orientation of the document we need to apply a rotation to the root page object.
            //By doing this we ensure that every page in the document is viewed rotated.
            int theDocID = Convert.ToInt32(theDoc.GetInfo(theDoc.Root, "Pages"));
            theDoc.SetInfo(theDocID, "/Rotate", "90");
        }

        theDoc.HtmlOptions.PageCacheEnabled = false;
        theDoc.HtmlOptions.AddForms = false;
        theDoc.HtmlOptions.AddLinks = false;
        theDoc.HtmlOptions.AddMovies = false;
        theDoc.HtmlOptions.FontEmbed = false;
        theDoc.HtmlOptions.UseResync = false;
        theDoc.HtmlOptions.UseVideo = false;
        theDoc.HtmlOptions.UseScript = false;
        theDoc.HtmlOptions.HideBackground = false;
        theDoc.HtmlOptions.Timeout = 60000;
        theDoc.HtmlOptions.BrowserWidth = 0;
        theDoc.HtmlOptions.ImageQuality = 101;

        // Add url to document.
        int theID = theDoc.AddImageUrl(url, true, 0, true);
        while (true)
        {
            if (!theDoc.Chainable(theID))
                break;
            theDoc.Page = theDoc.AddPage();
            theID = theDoc.AddImageToChain(theID);
        }
        //Flattening the pages (Whatever that means)
        for (int i = 1; i <= theDoc.PageCount; i++)
        {
            theDoc.PageNumber = i;
            theDoc.Flatten();
        }

        return theDoc.GetData();
    }
}
4

3 に答える 3

5

だからここに私がこれを解決した方法があります。

まず、HTML ページの高さを pdf 生成メソッドに渡す必要があったため、pdf 化するページにこれを追加しました。

<asp:HiddenField ID="hfHeight" runat="server" />

およびコードビハインドで:

protected void Page_Init(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string scriptKey = "WidhtHeightForPdf";
        if (!Page.ClientScript.IsClientScriptBlockRegistered(scriptKey))
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<script>")
                .AppendLine("document.getElementById('" + hfHeight.ClientID + "').value = document.body.clientHeight;")
                .AppendLine("</script>");

            Page.ClientScript.RegisterStartupScript(typeof(Page), scriptKey, sb.ToString());
        }
    }
}

これで、pdf 生成メソッドを呼び出すときに、HTML の高さを渡すことができます。高さを取得したら、高さがpdfページに収まるようにpdf「ビューポート」の幅を計算するだけです。

int intHTMLWidth = height.Value * Convert.ToInt32(theDoc.Rect.Width / theDoc.Rect.Height);

HtmlOptions次に、次のいずれかを介して BrowserWidth パラメータを指定しますtheDoc

theDoc.HtmlOptions.BrowserWidth = intHTMLWidth;

または に URL を追加する場合theDoc:

int theID = theDoc.AddImageUrl(url, true, intHTMLWidth, true);

編集:これで質問が解決したので、回答としてマークします。次に行うことは、HTML の幅と高さに基づいてプロトレイトまたはランドスケープ モードで PDF を作成し、PDF ページで最大のスペースが使用されるようにすることです。

于 2010-01-26T10:11:48.600 に答える
1

これはもう少し簡単かもしれません

    /// <summary>
    /// Calculate the height of given html
    /// </summary>
    /// <param name="html"></param>
    /// <returns></returns>
    public int CalculateHeight(string html)
    {
        int id = _Document.AddImageHtml(html);
        int height = (int)(_Document.GetInfoInt(id, "ScrollHeight") * PixelToPointScale);
        _Document.Delete( id );
        return height;
    }

[編集] まあ scrollHeight は ver8 で失敗しますが、これは機能します

    private int AddImageHtml(string html)
    {
        try
        {
            return _Document.AddImageHtml("<div id='pdfx-div-pdf-frame' class='abcpdf-tag-visible' style='abcpdf-tag-visible: true; border: 1px solid red'>" + html + "</div>");
        }
        catch (Exception ex)
        {
            throw new Exception(html, ex);
        }
    }

    private double GetElementHeight(int id)
    {
        abcpdf.XRect[] tagRects = _Document.HtmlOptions.GetTagRects(id);
        string[] tagIds = _Document.HtmlOptions.GetTagIDs(id);

        for (int i=0;i<tagRects.Length;i++)
        {
            abcpdf.XRect rect = tagRects[i];
            string tagId = tagIds[i];
            if (string.Equals(tagId, "pdfx-div-pdf-frame", StringComparison.CurrentCultureIgnoreCase))
            {
                return rect.Height;
            }
        }
        return -1;
    }
于 2012-05-01T00:27:37.533 に答える