2010-01-25 14 views
5

Sto utilizzando abcPdf per convertire un rapporto HTML in un file pdf. Il pdf deve essere una singola pagina A4 orizzontale.Comunica a abcPdf di ridimensionare l'html per adattarlo a una singola pagina pdf

Sai se c'è un modo per dire a abcPdf di ridimensionare la pagina HTML per adattarla a una singola pagina nel pdf? Ho provato a utilizzare Magnify() method e ridimensiona il contenuto, ma lo spezza ancora in pagine, anche se si adatta a una pagina. Mi sono grattato la testa per un po 'e mi chiedo se qualcuno lo ha fatto.

Ecco il codice che sto utilizzando in questo momento:

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(); 
    } 
} 

risposta

5

Quindi, ecco come ho risolto questo.

Prima di tutto, avevo bisogno l'altezza della pagina HTML da passare al metodo pdf di generazione, così ho aggiunto questo sulla pagina per essere pdf-ed:

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

e nel codice dietro :

Ora, quando chiamo il metodo di generazione di file PDF, posso passarlo all'altezza dell'HTML. Una volta che ho l'altezza è tutta una questione di calcolo della larghezza del pdf "finestra" in modo tale che l'altezza si adatti alla pagina pdf:

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

e quindi specificare il parametro BrowserWidth sia attraverso HtmlOptions di theDoc:

theDoc.HtmlOptions.BrowserWidth = intHTMLWidth; 

o quando si aggiunge l'url per theDoc:

EDIT: Questo risolve il problema, così ho intenzione per contrassegnarlo come una risposta. Ora la prossima cosa da fare è creare il pdf in modalità protrait o landscape in base alla larghezza e all'altezza dell'HTML, in modo che lo spazio massimo venga utilizzato nella pagina pdf.

+0

Hai finito e funziona? –

+0

Ciao mike o beon qualcuno ha ide di seguito problema http://stackoverflow.com/questions/22069825/abcpdf-not-showing-full-table-data – SivaRajini

1

Questo potrebbe essere un po 'più semplice

/// <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; 
    } 

[modifica] Bene scrollHeight riesce con ver8 questo funziona se

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; 
    } 
0

Nel caso in cui si utilizza il motore 'Gecko', questo motore non lo fa supporta 'GetInfoInt', quindi è necessario scrivere qualche javascript per ottenere l'altezza. Eseguire prima un rendering fittizio per determinare l'altezza e quindi impostare questa altezza su AbcDoc originale.

using (var tempDoc = new Doc()) 
       { 
        tempDoc.HtmlOptions.Engine = EngineType.Gecko; 
        tempDoc.HtmlOptions.Media = MediaType.Print; 
        tempDoc.HtmlOptions.UseScript = true; 
        if (width.HasValue) 
         tempDoc.HtmlOptions.BrowserWidth = width.Value; 

        tempDoc.HtmlOptions.OnLoadScript = " window.onbeforeprint = function() { document.documentElement.abcpdf = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);}"; 
        int theTempID = tempDoc.AddImageHtml(htmlData); 

        int height = Convert.ToInt32(tempDoc.HtmlOptions.GetScriptReturn(theTempID)); 

        tempDoc.Clear(); 
        tempDoc.Dispose(); 

        theDoc.MediaBox.Height = height; 
        theDoc.Rect.String = theDoc.MediaBox.String; 
        theDoc.AddImageHtml(htmlData); 
       } 
Problemi correlati