开发者

iTextSharp how to rotate/switch page from landscape to portrait

I'm using iTextSharp to merge multiple PDF files into a single Pdf. I found a code sample or two on the web as to how to accomplish this task.

They all work, with no apparent issues, as I'm able to merge multiple PDF files into a single PDF.

The issue that I do have is that I would like for all the pages to be in PORTRAIT, as some of the PDF files have pages in LANDSCAPE and I would like for them to be rotated to PORTRAIT. I do not mind that they will either be upside down or sideways, but they must all be in portrait.

Looking at the code sections in the examples listed:

page = writer.GetImportedPage(reader, i);
rotation = reader.GetPageRotation(i);

always returns the page rotation value as 0 (zero) thus the code section

if (rotation == 90 rotation == 270)
{
    cb.AddTemplate(page, 0, -1f, 1f, 0, 0, 
                         reader.GetPageSizeWithRotation(i).Height);
}

never gets executed (if that is what is supposed to do, rotating the page).

So, based on the code in the link of the 1st code sample page = writer.GetImportedPage(reader, i) how would I go about to change the page layout of the page from Landscape to Portrait, before I add it开发者_StackOverflow中文版 to the new merged PDF document with cb.AddTemplate...?

PS. Determining whether a page is either landscape or portrait I use the following piece of code obtained from SO (adapted for the code example above):

float pageXYRatio = page.Width / page.Height;
if (XYRatio > 1f)
{
    //page is landscape
}
else
{
    //page is portrait
}

Any help would be appreciated.

Thanks


I used something like this.

cb.PdfDocument.NewPage();
PdfImportedPage page1 = writer.GetImportedPage(reader, i);

Rectangle psize = reader.GetPageSizeWithRotation(i);
switch (psize.Rotation)
{
    case 0:
        cb.AddTemplate(page1, 1f, 0, 0, 1f, 0, 0);
        break;
    case 90:
        cb.AddTemplate(page1, 0, -1f, 1f, 0, 0, psize.Height);
        break;
    case 180:
        cb.AddTemplate(page1, -1f, 0, 0, -1f, 0, 0);
        break;
    case 270:
        cb.AddTemplate(page1, 0, 1.0F, -1.0F, 0, psize.Width, 0);
        break;
    default:
        break;
}


as you've found out, you cannot always count on PdfReader.GetPageRotation().

for example, if the Document object is created like this:

Document doc = new Document( new Rectangle(792, 612) );

PdfReader.GetPageRotation() will always return 0.

a really simplified way to decide whether a page is portrait or landscape is to compare the width and height of each page of each PDF you're combining. if the width is greater than the height of an individual page, add a dictionary entry to that page and explicitly set it's rotation. something like the following HTTP handler:

<%@ WebHandler Language='C#' Class='LandscapeToPortrait' %>
using System;
using System.IO;
using System.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;

public class LandscapeToPortrait : IHttpHandler {
  public void ProcessRequest (HttpContext context) {
    HttpResponse Response = context.Response;
    Response.ContentType = "application/pdf";
    PdfReader[] readers = {
      new PdfReader(CreateReaderBytes(false)),
      new PdfReader(CreateReaderBytes(true))
    };

    using (Document doc = new Document()) {
      using (PdfCopy copy = new PdfCopy(doc, Response.OutputStream)) {
        doc.Open();
        foreach (PdfReader reader in readers) {
          int n = reader.NumberOfPages;
          for (int page = 0; page < n;) {
            ++page;
            float width = reader.GetPageSize(page).Width;
            float height = reader.GetPageSize(page).Height;
            if (width > height) {
              PdfDictionary pageDict = reader.GetPageN(page);
              pageDict.Put(PdfName.ROTATE, new PdfNumber(90));
            }
            copy.AddPage(copy.GetImportedPage(reader, page));
          }
        }        
      }
    }
  }
  public bool IsReusable {
    get { return false; }
  }
  public byte[] CreateReaderBytes(bool isLandscape) {
    using (MemoryStream ms = new MemoryStream()) {
      Rectangle r = isLandscape
        ? new Rectangle(792, 612)
        : PageSize.LETTER
      ;
      using (Document doc = new Document(r)) {
        PdfWriter.GetInstance(doc, ms);
        doc.Open();
        for (int i = 0; i < 5; ++i) {
          doc.Add(new Phrase("hello world"));
          doc.NewPage();
        }
      }
      return ms.ToArray();
    }
  }
}

take a look at the PdfDictionary class. and here's a good thread from the mailing list explaining how iText[Sharp] stores the page rotation in every page.

and of course, you might want to invest in the book.


with that example http://alex.buayacorp.com/merge-pdf-files-with-itext-and-net.html I added the following line:

newDocument.SetPageSize(documents[0].GetPageSizeWithRotation(1));*

newDocument = new Document();
PdfWriter pdfWriter = PdfWriter.GetInstance(newDocument, outputStream);

// START PAGE ORIENTATION FROM 1st Document 1st Page
newDocument.SetPageSize(documents[0].GetPageSizeWithRotation(1));
// END PAGE ORIENTATION
newDocument.Open();
PdfContentByte pdfContentByte = pdfWriter.DirectContent;

My pdfs are built from SSRS and they have the same size, so I use the 1st page of the 1st document (I suppose)


// Instantiate the imported page as an Image

const float HALF_INCH = 36f;
// currentPosY is used to keep track of the current Y position.

PdfImportedPage page = writer.GetImportedPage(reader, j);
float scale = ((currentPosY - HALF_INCH - 10f) / page.Height);
Image imgP = Image.GetInstance(page);

if (page.Width > page.Height) { // Auto-detect landscape
 scale = ((currentPosY - HALF_INCH - 10f) / page.Width);
 imgP.RotationDegrees = 90f;   // could be 270f
}

imgP.ScalePercent(scale * 100f);
imgP.SetAbsolutePosition(HALF_INCH, HALF_INCH);
imgP.CompressionLevel = 9;
imgP.Border = Image.BOX;
imgP.BorderWidth = 1f;

document.Add(imgP);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜