I'm creating a pdf file from an large image, but my image is too large, and it does not fit in the only page. then i need split this image to create more pages.
any idea?
public FileResult ResultadoParaPdf(string file)
{
string fileStringReplace = file.Replace("data:image/png;base64,", "");
var image = Convert.FromBase64String(fileStringReplace);
const int HorizontalMargin = 40;
const int VerticalMargin = 40;
using (var outputMemoryStream = new MemoryStream())
{
using (var pdfDocument = new Document(PageSize.A4, HorizontalMargin, HorizontalMargin, VerticalMargin, VerticalMargin))
{
iTextSharp.text.pdf.PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, outputMemoryStream);
pdfWriter.CloseStream = false;
pdfDocument.Open();
PdfPTable table = new PdfPTable(1);
table.WidthPercentage = 100;
Image img = Image.GetInstance(image);
img.WidthPercentage = 100;
PdfPCell c = new PdfPCell(img, true);
c.Border = PdfPCell.NO_BORDER;
c.Padding = 5;
c.Image.ScaleToFit(750f, 750f);
table.AddCell(c);
pdfDocument.Add(table);
pdfDocument.Close();
byte[] created = outputMemoryStream.ToArray();
outputMemoryStream.Write(created, 0, created.Length);
outputMemoryStream.Position = 0;
return File(created, "application/pdf", "teste.pdf");
}
}
}
Related
I have implemented the code but the problem is I am able to combine only one image into a single pdf but I want to combine multiple images into a single pdf. My code is:
public void ImagesToPdf(string[] imagepaths, string pdfpath)
{
using (var ms = new MemoryStream())
{
var srcImage = new Bitmap(imagepaths[0].ToString());
iTextSharp.text.Rectangle pageSize = new iTextSharp.text.Rectangle(0, 0, srcImage.Width, srcImage.Height);
var document = new iTextSharp.text.Document(pageSize, 0, 0, 0, 0);
iTextSharp.text.pdf.PdfWriter.GetInstance(document, ms).SetFullCompression();
document.Open();
var image = iTextSharp.text.Image.GetInstance(imagepaths[0].ToString());
document.Add(image);
document.Close();
File.WriteAllBytes(pdfpath, ms.ToArray());
}
}
Any suggestions will be of great help. Thank you
I have finally figured out how to do this task.
public static byte[] ConvertIntoSinglePDF(List<string> filePaths)
{
Document doc = new Document();
doc.SetPageSize(PageSize.A4);
var ms = new System.IO.MemoryStream();
{
PdfCopy pdf = new PdfCopy(doc, ms);
doc.Open();
foreach (string path in filePaths)
{
byte[] data = File.ReadAllBytes(path);
doc.NewPage();
Document imageDocument = null;
PdfWriter imageDocumentWriter = null;
switch (Path.GetExtension(path).ToLower().Trim('.'))
{
case "bmp":
case "gif":
case "jpg":
case "png":
imageDocument = new Document();
using (var imageMS = new MemoryStream())
{
imageDocumentWriter = PdfWriter.GetInstance(imageDocument, imageMS);
imageDocument.Open();
if (imageDocument.NewPage())
{
var image = iTextSharp.text.Image.GetInstance(data);
image.Alignment = Element.ALIGN_CENTER;
image.ScaleToFit(doc.PageSize.Width - 10, doc.PageSize.Height - 10);
if (!imageDocument.Add(image))
{
throw new Exception("Unable to add image to page!");
}
imageDocument.Close();
imageDocumentWriter.Close();
PdfReader imageDocumentReader = new PdfReader(imageMS.ToArray());
var page = pdf.GetImportedPage(imageDocumentReader, 1);
pdf.AddPage(page);
imageDocumentReader.Close();
}
}
break;
case "pdf":
var reader = new PdfReader(data);
for (int i = 0; i < reader.NumberOfPages; i++)
{
pdf.AddPage(pdf.GetImportedPage(reader, i + 1));
}
pdf.FreeReader(reader);
reader.Close();
break;
default:
break;
}
}
if (doc.IsOpen()) doc.Close();
return ms.ToArray();
}
}
Once you got the byte array then just just write all bytes into file like this
byte[] document= ImagesToPDF.ConvertIntoSinglePDF(images);
File.WriteAllBytes("cheque.pdf", document);
ASP.NET C# Code Less
string FileNamePdf = PdfFileName.Text;
Document document = new iTextSharp.text.Document(PageSize.A4, 10f, 10f, 10f, 10f);
var output = new FileStream(Path.Combine(ObjData.ParentFolderPath + "\\SaveLocation", FileNamePdf + ".pdf"), FileMode.Create);
var writer = PdfWriter.GetInstance(document, output);
document.Open();
foreach (HttpPostedFile file in FilesToConvert.PostedFiles)
{
Image image = iTextSharp.text.Image.GetInstance(file.InputStream);
image.ScaleAbsolute(575f, 820.25f);
document.Add(image);
writer.NewPage();
}
document.Close();
Is it possible to add encryption to a PDF dynamically created from multiple MemoryStreams?
Following on from my last question C# Append PDF file to MemoryStream - Cannot access a closed Stream I am trying to add PDF encryption.
From the example I have provided below, if the line pdfStamper.Close(); is commented out I do not get the error Cannot access a closed Stream, but nor is the encryption applied to the generated PDF.
Can somebody please advise as to where I am going wrong and if possible how to achieve a solution to my problem?
public MemoryStream CreateMemoryStream()
{
byte[] dynamicPdfBytes;
using (var dynamicPDfMemoryStream = new MemoryStream())
{
using (var document = new Document(PageSize.A4, 25, 25, 30, 30))
{
PdfWriter.GetInstance(document, dynamicPDfMemoryStream);
document.Open();
var pdfPTable = new PdfPTable(1)
{
TotalWidth = _totalWidth,
LockedWidth = true,
SpacingBefore = _spacingBefore,
SpacingAfter = _spacingAfter
};
float[] widths = { 272f };
pdfPTable.SetWidths(widths);
var image = Image.GetInstance(HttpContext.Current.Server.MapPath("/Images/logo.png"));
image.ScaleToFit(125f, 125f);
image.Alignment = Image.RIGHT_ALIGN;
var pdfPCell = new PdfPCell(image)
{
Border = 0,
HorizontalAlignment = Element.ALIGN_RIGHT
};
pdfPTable.AddCell(pdfPCell);
document.Add(pdfPTable);
}
dynamicPdfBytes = dynamicPDfMemoryStream.ToArray();
}
byte[] pdfBytes;
using (var pdfReader = new PdfReader(HttpContext.Current.Server.MapPath("/Documents/Test.pdf")))
{
using (var pdfMemoryStream = new MemoryStream())
{
var pdfStamper = new PdfStamper(pdfReader, pdfMemoryStream);
var acroFields = pdfStamper.AcroFields;
acroFields.SetField("TestField", "This is a test");
pdfStamper.FormFlattening = true;
pdfStamper.Close();
pdfBytes = pdfMemoryStream.ToArray();
}
}
var files = new List<byte[]> { dynamicPdfBytes, pdfBytes };
byte[] array;
using (var arrayMemoryStream = new MemoryStream())
{
var document = new Document(PageSize.A4, 25, 25, 30, 30);
var pdfWriter = PdfWriter.GetInstance(document, arrayMemoryStream);
document.Open();
var directContent = pdfWriter.DirectContent;
foreach (var bytes in files)
{
var pdfReader = new PdfReader(bytes);
var pdfStamper = new PdfStamper(pdfReader, arrayMemoryStream);
pdfStamper.SetEncryption(null, _password, PdfWriter.ALLOW_PRINTING, PdfWriter.STANDARD_ENCRYPTION_128);
var numberOfPages = pdfReader.NumberOfPages;
for (var i = 1; i <= numberOfPages; i++)
{
document.NewPage();
var page = pdfWriter.GetImportedPage(pdfReader, i);
directContent.AddTemplate(page, 0, 0);
}
pdfStamper.FormFlattening = true;
pdfStamper.Close();
}
document.Close();
array = arrayMemoryStream.ToArray();
}
var memoryStream = new MemoryStream();
memoryStream.Write(array, 0, array.Length);
memoryStream.Position = 0;
return memoryStream;
}
Any assistance would be much appreciated :-)
This may not be the most elegant of solutions, however it is a solution to this specific issue and I hope it proves useful to others.
The following code can be used in conjunction with the original sample code, simply comment out all pdfStamper references in the code above:
private MemoryStream SecureMemoryStream()
{
var memoryStream = CreateMemoryStream();
return GetSecureMemoryStream(memoryStream);
}
private MemoryStream GetSecureMemoryStream(MemoryStream memoryStream)
{
byte[] array;
using (var secureMemoryStream = new MemoryStream())
{
var pdfReader = new PdfReader(memoryStream);
using (var pdfStamper = new PdfStamper(pdfReader, secureMemoryStream))
{
pdfStamper.SetEncryption(null, _password, PdfWriter.ALLOW_PRINTING, PdfWriter.STANDARD_ENCRYPTION_128);
pdfStamper.FormFlattening = true;
}
array = secureMemoryStream.ToArray();
}
var outputStream = new MemoryStream();
outputStream.Write(array, 0, array.Length);
outputStream.Position = 0;
return outputStream;
}
When we use below code it add only one image. Is any other option to add image & text on every page?
private void AddHeader(string filephysicalpath, string nfile)
{
byte[] bytes = System.IO.File.ReadAllBytes(filephysicalpath);
String path = ConfigurationManager.AppSettings["Documentheader"].ToString() + Session["headerImg"];
Stream inputImageStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
Font blackFont = FontFactory.GetFont("Arial", 12, Font.BOLD, BaseColor.BLACK);
using (MemoryStream stream = new MemoryStream())
{
PdfReader reader = new PdfReader(bytes);
using (PdfStamper stamper = new PdfStamper(reader, stream))
{
int pages = reader.NumberOfPages;
for (int i = 1; i <= pages; i++)
{
string footer = Convert.ToString(Session["Footer"]);
if (Session["Footer"] != null)
{
// Phrase ft = new Phrase(footer, blackFont);
float marginLR = 36;
float marginB = 2;
float footerHeight = 10;
Rectangle pagesize = reader.GetCropBox(i);
if (pagesize == null)
{
pagesize = reader.GetPageSize(i);
}
Rectangle rect = new Rectangle(
pagesize.Left + marginLR, pagesize.Top + marginB,
pagesize.Right - marginLR, pagesize.Top + marginB + footerHeight
);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(inputImageStream);
image.SetAbsolutePosition(rect.Left, rect.Top - image.ScaledHeight);
var pdfContentByte = stamper.GetOverContent(1);
pdfContentByte.AddImage(image);
inputImageStream.Seek(0L, SeekOrigin.Begin);
// ct.AddElement(new PdfPTableHeader (image));
}
}
}
reader.Close();
bytes = stream.ToArray();
}
System.IO.File.WriteAllBytes(filephysicalpath, bytes);
}
In your loop you do
var pdfContentByte = stamper.GetOverContent(1);
pdfContentByte.AddImage(image);
I.e. you always use the OverContent of page 1 and add the image to it. Instead you should use the OverContent of page i:
var pdfContentByte = stamper.GetOverContent(i);
pdfContentByte.AddImage(image);
Furthermore, you should import the image only once, i.e. move the line
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(inputImageStream);
above the loop.
Have you try to set inputImageStream to beggining before next use?
inputImageStream.Seek(0L, SeekOrigin.Begin);
Meybe its pointer is on the end of stream and next call return empty image?
I am getting started working with iTextSharp and am having trouble doing something pretty straightforward. I have a template that I am populating with PdfStamper like so
PdfReader rdr = new PdfReader(#"C:\temp\Template.pdf");
PdfStamper stamper = new PdfStamper(rdr, new System.IO.FileStream(path = #"C:\temp\Created.pdf", System.IO.FileMode.Create));
stamper.AcroFields.SetField("softwarename", "Software");
stamper.FormFlattening = true;
AcroFields form = stamper.AcroFields;
form.GenerateAppearances = true;
stamper.Close();
rdr.Close();
I want to be able to have a field called "grid" or something like that, and populate it with a PdfPTable with all the formatting intact (I know I can do it all in strings, but I don't want that). Is there a preferred way to do this?
The PDFStamper documentation says that it takes all objects allowed, so I would use a combination of objects (or lists of objects) and flags. That way you can pass in all the info you need an manipulate it according the whatever logic you need.
The following code will place images in a grid equally across the top of the page using the PdfPTable.
Then you can use PdfTemplate and use the WriteSelectedRows method to write the contents of the PdfPTable to it.
PdfPTable table;
string inputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "input.pdf");
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "output.pdf");
List<ImageTextSharpModel> images
PdfPTable table = new PdfPTable(images.Count);
table.WidthPercentage = 100;
table.HorizontalAlignment = Element.ALIGN_RIGHT;
for (var i = 0; i < images.Count; i++)
{
var image = images[i];
try
{
PdfPCell cell = new PdfPCell();
cell.BorderWidth = 0;
cell.FixedHeight = image.Height;
cell.VerticalAlignment = Element.ALIGN_MIDDLE;
Paragraph p = new Paragraph();
float offset = 0;
var img = iTextSharp.text.Image.GetInstance(image.AbsolutePath);
img.ScaleToFit(image.Width, image.Height);
//Manually setting the location
if (image.Alignment == iTextSharp.text.Image.RIGHT_ALIGN)
{
offset = i == 0
? (((doc.PageSize.Width/images.Count) - doc.LeftMargin) - img.ScaledWidth)
: (((doc.PageSize.Width/images.Count) - doc.LeftMargin) - img.ScaledWidth) - cell.Width;
}
else if (image.Alignment == iTextSharp.text.Image.ALIGN_CENTER)
{
if (images.Count == 1)
{
offset = ((doc.PageSize.Width - img.ScaledWidth)/2) - doc.LeftMargin;
}
else
{
offset = (((doc.PageSize.Width/images.Count) - img.ScaledWidth)/2);
}
}
p.Add(new Chunk(img, offset, 0));
cell.AddElement(p);
table.AddCell(cell);
}
catch (Exception ex)
{
//Ignore
}
}
;
//add table to stamper
iTextSharp.text.pdf.PdfReader pdfReader = new iTextSharp.text.pdf.PdfReader(inputFile);
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (PdfStamper stamper = new PdfStamper(pdfReader, fs))
{
int PageCount = pdfReader.NumberOfPages;
for (int x = 1; x <= PageCount; x++)
{
PdfContentByte canvas = stamper.GetOverContent(x);
PdfTemplate tableTemplate = canvas.CreateTemplate(1500, 1300);
table.WriteSelectedRows(0, -1, 0, 1300, tableTemplate);
}
stamper.Close();
}
}
i have a pdf file. There is a footer on each page. now i want to replace a static text exist on footer with some other text. Please Help me.....
I have tried with following case but not success
PdfReader readere = new PdfReader(#"D:\MergedOutput.pdf");
for (int i = 1; i < readere.NumberOfPages; i++)
{
byte[] contentBytes = PdfEncodings.ConvertToBytes(PdfTextExtractor.GetTextFromPage(readere, i), PdfObject.TEXT_PDFDOCENCODING);
byte[] searchStringArray = PdfEncodings.ConvertToBytes("Side", PdfObject.TEXT_PDFDOCENCODING);
byte[] replacedByString = PdfEncodings.ConvertToBytes("Hello", PdfObject.TEXT_PDFDOCENCODING);
string searchString = PdfEncodings.ConvertToString(searchStringArray, PdfObject.TEXT_PDFDOCENCODING);
string contentString = PdfEncodings.ConvertToString(contentBytes, PdfObject.TEXT_PDFDOCENCODING);
string replaceString = PdfEncodings.ConvertToString(replacedByString, PdfObject.TEXT_PDFDOCENCODING);
if (contentString.Contains(searchString))
{
contentString = contentString.Replace(searchString, replaceString);
}
readere.SetPageContent(i, PdfEncodings.ConvertToBytes(contentString, PdfObject.TEXT_PDFDOCENCODING));
}
Suppose you have a byte array of PDF data or any PDF files. First convert this file to byte array.. after that we have to apply below code section. its working fine for me...
iTextSharp.text.Font blackFont = FontFactory.GetFont("Seoge UI", 10, iTextSharp.text.Font.NORMAL, new BaseColor(Color.FromArgb(97, 102, 116)));
//Path to where you want the file to output
string outputFilePath = "MergedOutputt.pdf";
//Path to where the pdf you want to modify is
//string inputFilePath = "D:\\MergedOutput.pdf";
try
{
using (Stream outputPdfStream = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
using (Stream outputPdfStream2 = new FileStream(outputFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
{
//Opens the unmodified PDF for reading
var reader = new PdfReader(MergedOutputStream.ToArray());
//Creates a stamper to put an image on the original pdf
var stamper = new PdfStamper(reader, outputPdfStream) { FormFlattening = true, FreeTextFlattening = true };
for (int i = 1; i <= reader.NumberOfPages; i++)
{
//Creates an image that is the size i need to hide the text i'm interested in removing
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(new Bitmap(120, 20), BaseColor.WHITE);
//Sets the position that the image needs to be placed (ie the location of the text to be removed)
image.SetAbsolutePosition(reader.GetPageSize(i).Width - 120, 42);
//Adds the image to the output pdf
stamper.GetOverContent(i).AddImage(image, true);
//Creates the first copy of the outputted pdf
PdfPTable table = new PdfPTable(1);
float[] width = new float[] { 38 };
table.SetTotalWidth(width);
PdfContentByte pb;
//Get PdfContentByte object for first page of pdf file
pb = stamper.GetOverContent(i);
cellSequenceNumber = new PdfPCell(new Phrase(new Chunk("Side " + i.ToString(), blackFont)));
cellSequenceNumber.Border = 0;
table.AddCell(cellSequenceNumber);
table.WriteSelectedRows(0, table.Rows.Count, reader.GetPageSize(i).Width - 82, 54, pb);
}
stamper.Close();
//Opens our outputted file for reading
var reader2 = new PdfReader(outputPdfStream2);
reader2.Close();
}
}
It will generate a pdf file named as "MergedOutputt.pdf"