Change pageSize of pdf before saving - c#

I receive a pdf as a byte[]. When I save this binary as pdf, pageSize is too big. I want to change the pageSize in the code.
Currently I am trying it this way, based on what I found in other questions:
using iTextSharp;
using iTextSharp.text;
using iTextSharp.text.pdf;
using (MemoryStream stream = new MemoryStream(pdfAsBinary))
{
using (PdfReader reader = new PdfReader(pdfAsBinary))
{
using (Document doc = new Document(PageSize.A4))
{
PdfWriter writer = PdfWriter.GetInstance(doc, stream);
PdfImportedPage page = writer.GetImportedPage(reader, 1);
image = Image.GetInstance(page);
using (var pdfStream = new FileStream(tempPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
{
PdfWriter pdfwriter = PdfWriter.GetInstance(doc, pdfStream);
doc.Open();
doc.SetPageSize(PageSize.A4);
image.ScalePercent(30f);
doc.Add(image);
doc.Close();
}
}
}
File.Copy(tempPath, pathToFile);
}
Or I tried using this method:
private static byte[] resizeToA4(byte[] inputDoc)
{
using (MemoryStream out = new MemoryStream())
{
using (PdfReader reader = new PdfReader(inputDoc))
{
using (Document doc = new Document(PageSize.A4))
{
PdfWriter writer = PdfWriter.GetInstance(doc, out);
}
}
return outPDF.ToArray();
}
None of the above is working and it feels like I'm overcomplicating things. How can I achieve my resizing of the pageSize to A4?

This method works for one-page-files.
public static void ScaleToA4self(byte[] pdfAsBinary, string locationOfPdfOut)
{
PdfReader reader = new PdfReader(pdfAsBinary);
Rectangle originalSize = reader.GetPageSize(1);
float originalHeight = originalSize.Height;
float originalWidth = originalSize.Width;
Rectangle newSize = PageSize.A4;
float newHeight = newSize.Height;
float newWidth = newSize.Width;
float scaleHeight = newHeight / originalHeight;
float scaleWidth = newWidth / originalWidth;
Document doc = new Document(newSize, 0, 0, 0, 0);
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(locationOfPdfOut, FileMode.Create));
doc.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, scaleWidth, 0, 0, scaleHeight, 0, 0);
doc.Close();
}

Related

Grab all of the pages of a PDF using textsharp

I am getting a pfd using the older version of itextsharp with this code
string Oldfile = #"C:/test.pdf"; // Gets the Template
(new FileInfo("C:/C:/test.pdf")).Directory.Create(); // Go create this folder if it's not there
string NewFile = "C:/test.pdf";
PdfReader reader = new PdfReader(Oldfile);
iTextSharp.text.Rectangle Size = reader.GetPageSizeWithRotation(1);
Document document = new Document(Size);
// MemoryStream memory_stream = new MemoryStream();
FileStream fs = new FileStream(NewFile, FileMode.Create, FileAccess.Write);
PdfWriter weiter = PdfWriter.GetInstance(document, fs);
document.Open();
PdfContentByte cb = weiter.DirectContent;
PdfImportedPage page = weiter.GetImportedPage(reader, 1);
//PdfImportedPage page2 = weiter.GetImportedPage(reader, 2);
cb.AddTemplate(page, 0, 0);
The problem I am having is when it gets that file it has 2 pages in that pdf but it only gets the 1st page and adds lines and saves the only 1st page of the pdf I want to be able to grab both of them or is there a way to merge them after wards
I bet you need to iterate all pages.
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace TestAnything
{
class Program
{
static void Main(string[] args)
{
List<string> filesToMerge = new List<string> { #"c:\temp\1.pdf", #"c:\temp\2.pdf" };
FileInfo destinationFile = new FileInfo(#"c:\temp\merge.pdf");
if (File.Exists(destinationFile.FullName))
File.Delete(destinationFile.FullName);
MergeFiles(filesToMerge, destinationFile);
}
public static void MergeFiles(List<string> sourceFiles, FileInfo destinationFile)
{
if (sourceFiles == null || sourceFiles.Count == 0)
throw new ArgumentNullException("blahhh.");
PdfReader reader = new PdfReader(sourceFiles[0]);
Document document = new Document(reader.GetPageSizeWithRotation(1));
PdfCopy writer = new PdfCopy(document, new FileStream(destinationFile.FullName, FileMode.Create));
document.Open();
try
{
foreach (string sourceFile in sourceFiles)
{
reader = new PdfReader(sourceFile);
reader.ConsolidateNamedDestinations();
for (int x = 1; x <= reader.NumberOfPages; x++)
writer.AddPage(writer.GetImportedPage(reader, x));
PRAcroForm form = reader.AcroForm;
if (form != null)
writer.CopyAcroForm(reader);
}
}
finally
{
if (document.IsOpen())
document.Close();
}
}
}
}

how to add pagenumbers to every pdf page using itextsharp

here is What i want i want to add page numbers to every pdf page that i generated on the fly.
i used on end page method but it did not worked out even when i added the doc bottom margin.
I decided to add the page numbers after the pdf is generated from the file path.
here is my code for generating pdf:
Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 35);
PdfWriter wri = PdfWriter.GetInstance(doc, new FileStream("t5.pdf", FileMode.Create));
doc.Open();//Open Document to write
iTextSharp.text.Font font8 = FontFactory.GetFont("ARIAL", 7);
Paragraph paragraph = new Paragraph("Some content");
doc.Add(paragraph);
doc.Add(paragraph);// add paragraph to the document
doc.Close();
FileStream stream = File.OpenRead("t5.pdf");
byte[] fileBytes = new byte[stream.Length];
stream.Read(fileBytes, 0, fileBytes.Length);
stream.Close();
AddPageNumbers(fileBytes);
using (Stream file = File.OpenWrite("t5.pdf"))
{
file.Write(fileBytes, 0, fileBytes.Length);
}
}
and her is my add pagenumbers method:
MemoryStream ms = new MemoryStream();
PdfReader reader = new PdfReader(pdf);
int n = reader.NumberOfPages;
iTextSharp.text.Rectangle psize = reader.GetPageSize(1);
Document document = new Document(psize, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.GetInstance(document, ms);
document.Open();
PdfContentByte cb = writer.DirectContent;
int p = 0;
for (int page = 1; page <= reader.NumberOfPages; page++)
{
document.NewPage();
p++;
PdfImportedPage importedPage = writer.GetImportedPage(reader, page);
cb.AddTemplate(importedPage, 0, 0);
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.BeginText();
cb.SetFontAndSize(bf, 10);
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, +p + "/" + n, 100, 450, 0);
cb.EndText();
}
document.Close();
return ms.ToArray();
how ever it does not add the page numbers to the pdf document so what is the alternatives here? what can i do.
When posting a question here, please only post the smallest amount of code possible. Your "create a sample PDF with multiple pages" is 116 lines long. Inside of it you've got complicated PdfPTable and DataTable logic that is 100% unrelated to the problem. Instead, the following 13 lines is enough to make a multiple page PDF:
//Create a sample multiple page PDF and place it on the desktop
var outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "t5.pdf");
using (var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
for (var i = 0; i < 1000; i++) {
doc.Add(new Paragraph(String.Format("This is paragraph #{0}", i)));
}
doc.Close();
}
}
}
Second, get rid of try/catch. Those are great for production (sometimes) but at the development level that's why we have IDEs and compilers, they'll tell us specifically what's wrong.
Now on to the bigger problem, you need to keep these two processes separate from each other. Every single brace and object from part part #1 must be closed, done and accounted for. Part #2 then needs to be fed a completely valid PDF but neither of the two parts should be "aware" of each other or depend on each other.
Since you just borrowed some code that wasn't intended for what you're trying to do I'm going to also ignore that and use some code that I know specifically will work. Also, since you're open to using a MemoryStream in the first place I'm just going to avoid writing to disk until I need to. Below is a full working sample that creates a multiple page and then adds page numbers in a second pass.
//Will hold our PDF as a byte array
Byte[] bytes;
//Create a sample multiple page PDF, nothing special here
using (var ms = new MemoryStream()) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, ms)) {
doc.Open();
for (var i = 0; i < 1000; i++) {
doc.Add(new Paragraph(String.Format("This is paragraph #{0}", i)));
}
doc.Close();
}
}
//Store our bytes before
bytes = ms.ToArray();
}
//Read our sample PDF and apply page numbers
using (var reader = new PdfReader(bytes)) {
using (var ms = new MemoryStream()) {
using (var stamper = new PdfStamper(reader, ms)) {
int PageCount = reader.NumberOfPages;
for (int i = 1; i <= PageCount; i++) {
ColumnText.ShowTextAligned(stamper.GetOverContent(i), Element.ALIGN_CENTER, new Phrase(String.Format("Page {0} of {1}", i, PageCount)), 100, 10 , 0);
}
}
bytes = ms.ToArray();
}
}
var outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "t5.pdf");
System.IO.File.WriteAllBytes(outputFile, bytes);

ItextSharp changing Userunit

If I change the userunit to 10 the size shown in acrobat is correct but when I import the pdf in CorelDrawX3 and X7 or in Rasterlink Pro5 the size get changed back to before Userunit was changed.
I have to change the userunit because the pdf is to big.
Here is my coding.
public void PDFUserUnit(string FileIn, string FileOut)
{
using (var doc = new Document(new Rectangle(10000f, 16000f)))
{
using (var fs = new FileStream(FileOut, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (var writer = PdfWriter.GetInstance(doc, fs))
{
iTextSharp.text.pdf.ByteBuffer.HIGH_PRECISION = true;
writer.SetPdfVersion(PdfWriter.PDF_VERSION_1_6);
writer.Userunit = 10f;
doc.Open();
doc.NewPage();
PdfReader reader = new PdfReader(FileIn);
PdfContentByte canvas = writer.DirectContent;
PdfTemplate tmp = writer.GetImportedPage(reader, 1);
canvas.AddTemplate(tmp, 1f, 0, 0, 1f, 0, 0);
doc.Close();
}
}
}
}

Stack overflow exception on itextsharp document.close

I am merging multiple PDF into one single file.
here is my code:
string[] files = Directory.GetFiles(FolderName);
using (FileStream fs = new FileStream(PdfOutputFile, FileMode.Create))
{
Document doc = new Document();
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
doc.Open();
foreach (string percorsoFile in files)
{
PdfContentByte cb = writer.DirectContent;
PdfReader reader = new PdfReader(percorsoFile);
int numpagine = reader.NumberOfPages - PageAddedByWord;
for (int pagina = 1; pagina <= numpagine; pagina++)
{
int rotazione = reader.GetPageSizeWithRotation(pagina).Rotation;
PdfImportedPage page = writer.GetImportedPage(reader, pagina);
doc.NewPage();
if (rotazione == 90 || rotazione == 270)
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(pagina).Height);
else
cb.AddTemplate(page, 0f, 0f);
}
reader.Close();
}
doc.Close();
}
And I get stack overflow exception on the doc.Close() line, but I can't understand why. I close every reader as soon as I am done with that file. I get this exception only with large sets of pdf (like 2000).
thank's for the help.
SOLVED, I used PdfSmartCopy instead of pdfwriter. Now the code looks like this
Document doc = new Document();
PdfSmartCopy pdfCopy = new PdfSmartCopy(doc, ms);
doc.Open();
foreach (var percorsoFilePdf in files)
{
PdfReader reader = new PdfReader(percorsoFilePdf);
int numpagine = reader.NumberOfPages;
for (int I = 1; I <= numpagine-PageAddedByWord; I++)
{
doc.SetPageSize(reader.GetPageSizeWithRotation(1));
PdfImportedPage page = pdfCopy.GetImportedPage(reader, I);
pdfCopy.AddPage(page);
}
//Clean up
//pdfCopy.FreeReader(reader);
reader.Close();
}
//Clean up
doc.Close();
SharedMethods.MemoryStreamToFile(ms, PdfOutputFile);
also using a memorystream instead of a file stream is much faster, and the process doesn't get "too large".

How to rotate text in iTextSharp?

I have searched the web but it looks like that it is not that easy, how can i rotate my text?
Document doc = new Document(new iTextSharp.text.Rectangle(600, 800), 0, 0, 0, 0);
PdfWriter.GetInstance(doc, new FileStream(Directory.GetCurrentDirectory() + "/genpdf.pdf", FileMode.Create));
doc.Open();
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(file);
Chunk c1 = new Chunk("~Comment~"); //rotate 270°
doc.Add(image);
doc.Add(text);
doc.Close();
The answer is in Rotate text answer
The writer is a PdfWriter type, you can get it like:
using (stream = new FileStream(temp_filename, FileMode.Create))
{
iTextSharp.text.Document document = new iTextSharp.text.Document();
PdfWriter writer = PdfWriter.GetInstance(document, stream);

Categories