ITextSharp как повернуть/переключить страницу с пейзажа на портрет
Я использую iTextSharp для объединения нескольких файлов PDF в один Pdf. Я нашел пример кода или два в Интернете о том, как выполнить эту задачу.
Все они работают без видимых проблем, так как я могу объединить несколько PDF файлов в один PDF файл.
Проблема, которая у меня есть, заключается в том, что я хотел бы, чтобы все страницы находились в ПОРТРЕТЕ, так как некоторые из файлов PDF имеют страницы в LANDSCAPE, и я хотел бы, чтобы они были повернуты в ПОРТРЕТ. Я не против, что они либо перевернут, либо боком, но все они должны быть в портрете.
Глядя на разделы кода в приведенных примерах:
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. Определяя, является ли страница ландшафтной или портретной, я использую следующий фрагмент code, полученный из SO (адаптированный для примера кода выше):
float pageXYRatio = page.Width / page.Height;
if (XYRatio > 1f)
{
//page is landscape
}
else
{
//page is portrait
}
Любая помощь будет оценена.
Спасибо
Ответы
Ответ 1
как вы выяснили, вы не всегда можете рассчитывать на PdfReader.GetPageRotation().
например, если объект Document создается следующим образом:
Document doc = new Document( new Rectangle(792, 612) );
PdfReader.GetPageRotation()
будет всегда возвращать 0.
действительно упрощенный способ решить, является ли страница портретом или ландшафтом, чтобы сравнить ширину и высоту каждой страницы каждого 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] сохраняет вращение страницы на каждой странице.
и, конечно же, вы можете инвестировать в книгу.
Ответ 2
Я использовал что-то вроде этого.
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;
}
Ответ 3
с этим примером 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-ю страницу 1-го документа (я полагаю)
Ответ 4
// 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);