iTextSharp, как повернуть / переключить страницу из пейзажа в портрет - PullRequest
16 голосов
/ 17 марта 2011

Я использую iTextSharp для объединения нескольких файлов PDF в один файл PDF. Я нашел пример кода или два о том, как выполнить эту задачу.

Все они работают без видимых проблем, так как я могу объединить несколько файлов PDF в один PDF.

Проблема, с которой я столкнулся, заключается в том, что я хотел бы, чтобы все страницы были в PORTRAIT, поскольку некоторые из файлов PDF имеют страницы в LANDSCAPE, и я хотел бы, чтобы они были повернуты в PORTRAIT. Я не против, чтобы они были либо вверх ногами, либо боком, но все они должны быть в портрете.

Глядя на разделы кода в приведенных примерах:

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

всегда возвращает значение поворота страницы как 0 (ноль), таким образом, секция кода

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

никогда не выполняется (если это то, что предполагается делать, вращая страницу).

Итак, основываясь на коде, указанном в ссылке на 1-й пример кода page = writer.GetImportedPage(reader, i), как мне изменить макет страницы page с альбомной на портретную, прежде чем добавить его в новый объединенный PDF-документ с cb.AddTemplate...?

PS. Чтобы определить, является ли страница альбомной или портретной, я использую следующий фрагмент кода , полученный из SO (адаптированный для приведенного выше примера кода):

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

Любая помощь будет оценена.

Спасибо

Ответы [ 4 ]

13 голосов
/ 18 марта 2011

Я использовал что-то вроде этого.

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;
}
6 голосов
/ 18 марта 2011

как вы узнали, вы не всегда можете рассчитывать на PdfReader.GetPageRotation () .

, например, если объект Document создан следующим образом:

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

PdfReader.GetPageRotation() будет всегда вернет 0.

a действительно упрощенный способ решить, является ли страница портретной или альбомной, заключается в сравнении ширины и высотыкаждой страницы каждого PDF-файла, который вы комбинируете.если ширина больше, чем высота отдельной страницы, добавьте словарную статью на эту страницу и явно установите ее вращение.что-то вроде следующего обработчика HTTP :

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

взгляните на класс PdfDictionary вот хорошая ветка из списка рассылки , объясняющая, как iText [Sharp] сохраняет ротацию страниц на каждой странице.

и, конечно, вы можете инвестировать в книгу .

3 голосов
/ 03 августа 2011

с этим примером http://alex.buayacorp.com/merge-pdf-files-with-itext-and-net.html Я добавил следующую строку:

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;

Мои PDF-файлы построены из SSRS и имеют одинаковый размер, поэтому я использую первую страницу 1-го документа (я полагаю)

0 голосов
/ 03 января 2013
// 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...