I've a java code to create a PDF temporary file and save it into a BLOB field DB. PDF is generated correctly, and BLOB is saved into DB. When I recreate PDF this is returned without whitespace char! Probably the problem is codification Base64 of bytearrayoutputstream. This is my code
public ByteArrayOutputStream generaFatturaStampaPDF(Fattura fattura) {
try {
Document document = new Document(PageSize.A4, 72, 72, 120, 90);
String tempdir = System.getProperty("java.io.tmpdir");
if ( !(tempdir.endsWith("/") || tempdir.endsWith("\\")) )
tempdir = tempdir + System.getProperty("file.separator");
File tempFattura = File.createTempFile("fattura",".pdf", new File(tempdir));
tempFattura.deleteOnExit();
setFileTempFattura(tempFattura.toString());
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(tempFattura));
writer.setPdfVersion(PdfWriter.VERSION_1_7);
writer.setPageEvent(new HeaderFooter());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter docWriter = null;
docWriter = PdfWriter.getInstance(document, baos);
docWriter.setPdfVersion(PdfWriter.VERSION_1_7);
docWriter.setPageEvent(new HeaderFooter());
document.open();
addMetaDataFattura(document);
Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD, BaseColor.BLACK);
Paragraph paragrafoFattura = new Paragraph();
paragrafoFattura.setAlignment(Element.ALIGN_CENTER);
Chunk c = new Chunk("Fattura");
c.setFont(catFont);
paragrafoFattura.add(c);
document.add(paragrafoFattura);
intestazioneFatturaStampa(writer, fattura);
intestazioneFatturaStampa(docWriter, fattura);
addEmptyLine(document, 7);
float[] widths = { 8f, 2f };
PdfPTable table = new PdfPTable(widths);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.setWidthPercentage(100);
table.setHeaderRows(1);
addCenterTableHeaderBold(table, "Descrizione", true, 12);
addCenterTableHeaderBold(table, "Totale", true, 12);
Double somma = 0.0;
Iterator<FatturaDettaglio> iterator = fattura.getFatturaDettaglios().iterator();
while (iterator.hasNext()) {
FatturaDettaglio fatturaDettaglio = iterator.next();
somma += fatturaDettaglio.getPrezzo();
}
addCenterTableHeaderBoldAllignLeft(table, fattura.getFatturaDettaglios().size()
+ " Richieste di Preventivo ", false, 12);
addCenterTableHeaderBold(table, "€ " + arrotonda(somma), false, 12);
Iterator<CreditoDebito> iterator2 = fattura.getCreditoDebitos().iterator();
while (iterator2.hasNext()) {
CreditoDebito creditoDebito = iterator2.next();
addCenterTableHeaderBoldAllignLeft(table, creditoDebito.getNote(), false, 12);
String segno = "";
if (creditoDebito.getTipo().equals("C")) {
segno = "-";
somma = somma - creditoDebito.getImporto();
}
if (creditoDebito.getTipo().equals("D")) {
segno = "";
somma = somma + creditoDebito.getImporto();
}
addCenterTableHeaderBold(table, "€ " + segno
+ arrotonda(creditoDebito.getImporto()), false, 12);
}
document.add(table);
addEmptyLine(document, 2);
float[] widths1 = { 2f, 1f };
PdfPTable table1 = new PdfPTable(widths1);
table1.setHorizontalAlignment(Element.ALIGN_RIGHT);
table1.setWidthPercentage(60);
addCenterTableHeader(table1, "Totale Imponibile netto", true);
addCenterTableHeader(table1, "€ " + arrotonda(somma), false);
addCenterTableHeader(table1, "IVA", true);
addCenterTableHeader(table1, "€ " + arrotonda(somma * 20 / 100), false);
addCenterTableHeader(table1, "Totale Fattura", true);
addCenterTableHeader(table1, "€ " + arrotonda(somma + somma * 20 / 100), false);
document.add(table1);
addEmptyLine(document, 2);
paragrafoFattura.setAlignment(Element.ALIGN_LEFT);
Chunk datiPagamento =
new Chunk("Dettagli pagamento:\nMetodo: "
+ fattura.getAzienda().getMetodoPagamento()
+ "\nIBAN: IT xx X xxxxx xxxxx xxxxxxxxxxx");
document.add(datiPagamento);
addEmptyLine(document, 5);
Chunk dettagliEstrattoContoTesto =
new Chunk(
"Per maggiori dettagli sulle richieste di preventivo e eventuali promozioni consultare l'estratto conto allegato");
dettagliEstrattoContoTesto.setFont(new Font(Font.FontFamily.TIMES_ROMAN, 10,
Font.NORMAL, BaseColor.BLACK));
document.add(dettagliEstrattoContoTesto);
document.close();
docWriter.close();
return baos;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Try compressing the string containing the PDF first, then putting it into the DB compressed, then uncompress it when pulling it out. This will ensure that nothing is changed and the string is handled as binary.
Related
below the code using one text field, two list boxes and one signature field. selecting an entry of listbox domicilation updates the entries of listbox legalForm. The newDateField currently servers as debug field, it contains the last listbox value that was updated. I would like to know why the result cannot be signed. It must be related to the javascript of the list boxes... Kindly help
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
import org.apache.pdfbox.pdmodel.interactive.action.PDAnnotationAdditionalActions;
import org.apache.pdfbox.pdmodel.interactive.action.PDFormFieldAdditionalActions;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
import org.apache.pdfbox.pdmodel.interactive.form.*;
import java.awt.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class AnaCreditForm {
public static void main(String[] args) {
System.out.println("Creating pdf docoument including signature field");
try {
// Create a new document with an empty page.
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
String javaScript = "var now = util.printd('yyyy-mm-dd', new Date());"
+ "var ndf = this.getField('newDateField');"
+ "ndf.value = now;"
// + "this.getField('signatureField').display=display.hidden;"
// + "var formReady = false;"
+ "var anacredit = { '-': [['-', '-']], "
+ " 'Luxembourg': [[ '-', '-'], ['LU01 Entreprise individuelle', 'LU01'],[ 'LU06 Société anonyme', 'LU06'] ,['LU14 Société civile','LU14']] , "
+ " 'Germany': [[ '-', '-'], ['DE201 Aktiengesellschaft', 'DE201'], ['DE602 Eingetragener Verein', 'DE602'], ['DE205 Investmentaktiengesellschaft', 'DE205']], "
+ " 'Greece': [[ '-', '-'], ['GR906 Εταιρία Περιορισμένης Ευθύνης/Etería Periorisménis Euthínis', 'GR906'], ['GR912 Κοινοπραξία/Kinopraxia', 'GR912'], ['GR999 Λοιπά/Lipa', 'GR999']] };";
// Create an action as JavaScript action
PDActionJavaScript jsAction = new PDActionJavaScript();
jsAction.setAction(javaScript);
// Set the action to be executed when the document is opened
document.getDocumentCatalog().setOpenAction(jsAction);
// Adobe Acrobat uses Helvetica as a default font and
// stores that under the name '/Helv' in the resources dictionary
PDFont font = PDType1Font.HELVETICA;
PDResources resources = new PDResources();
resources.put(COSName.getPDFName("Helv"), font);
PDDocumentCatalog pdCatalog = document.getDocumentCatalog();
PDAcroForm pdAcroForm = new PDAcroForm(document);
pdCatalog.setAcroForm(pdAcroForm);
pdAcroForm.setDefaultResources(resources);
String defaultAppearanceString = "/Helv 0 Tf 0 g";
pdAcroForm.setDefaultAppearance(defaultAppearanceString);
PDTextField newDateField = new PDTextField(pdAcroForm);
newDateField.setPartialName("newDateField");
defaultAppearanceString = "/Helv 12 Tf 0 g";
newDateField.setDefaultAppearance(defaultAppearanceString);
pdAcroForm.getFields().add(newDateField);
PDAnnotationWidget widget = newDateField.getWidgets().get(0);
PDRectangle rect = new PDRectangle(50, 450, 500, 15);
widget.setRectangle(rect);
widget.setPage(page);
// make sure the annotation is visible on screen and paper
widget.setPrinted(true);
// Add the annotation to the page
page.getAnnotations().add(widget);
//newDateField.setValue("value in newly created text field");
//textBox.setActions(fieldActions);
PDListBox domicilation = new PDListBox(pdAcroForm);
domicilation.setPartialName("domicilation");
List<String> displayList = Arrays.asList("-", "Germany", "Luxembourg", "Greece");
List<String> exportList = Arrays.asList("-", "Germany", "Luxembourg", "Greece");
domicilation.setOptions(exportList, displayList);
defaultAppearanceString = "/Helv 12 Tf 0 g";
domicilation.setDefaultAppearance(defaultAppearanceString);
pdAcroForm.getFields().add(domicilation);
String jsListBox0 =
"var f = this.getField('domicilation');"
+ "var r = this.getField('legalForm');"
+ " console.println('domicilation ' + f.value + 'legalForm' + r.value);"
+ "f.setAction('Keystroke', 'fft();');"
+ "function fft() { if (event.willCommit)"
+ "{ console.println('domiciliation' + event.change + ' ' + event.value); "
+ "r.setItems( anacredit[event.value] );"
+ "f.value=event.value) ; ndf.value= event.value;"
+ " }}";
// + "r.value='-'; formReady=false; }}";
PDFormFieldAdditionalActions fieldActions = new PDFormFieldAdditionalActions();
PDActionJavaScript jsKeystrokeAction = new PDActionJavaScript();
//jsKeystrokeAction.setAction("app.alert(\"On 'keystroke' action\")");
jsKeystrokeAction.setAction(jsListBox0);
fieldActions.setK(jsKeystrokeAction);
domicilation.setActions(fieldActions);
PDAnnotationWidget widget2 = domicilation.getWidgets().get(0);
PDRectangle rect2 = new PDRectangle(50, 380, 500, 50);
widget2.setRectangle(rect2);
widget2.setPage(page);
// make sure the annotation is visible on screen and paper
widget2.setPrinted(true);
//PDAnnotationAdditionalActions annotationActions = new PDAnnotationAdditionalActions();
// Add the annotation to the page
page.getAnnotations().add(widget2);
domicilation.setValue("-");
PDListBox legalForm = new PDListBox(pdAcroForm);
legalForm.setPartialName("legalForm");
List<String> displayList2 = Arrays.asList("-");
List<String> exportList2 = Arrays.asList(" ");
legalForm.setOptions(exportList2, displayList2);
defaultAppearanceString = "/Helv 12 Tf 0 g";
legalForm.setDefaultAppearance(defaultAppearanceString);
pdAcroForm.getFields().add(legalForm);
PDAnnotationWidget widget3 = legalForm.getWidgets().get(0);
PDRectangle rect3 = new PDRectangle(50, 310, 500, 50);
widget3.setRectangle(rect3);
widget3.setPage(page);
// make sure the annotation is visible on screen and paper
widget3.setPrinted(true);
String jsListBox2 = "var lb = this.getField('legalForm'); "
+ "console.println('in legalForm action ' + lb.value);"
+ "lb.setAction('Keystroke', 'fft2();');"
+ "function fft2() { if (event.willCommit)"
+ "{ console.println('in legalForm action ' + event.change + ' ' + event.value);"
+ "lb.value=event.value; ndf.value= event.value;}}";
// + "console.println(formReady);"
// + "lb.setAction('Keystroke', 'flb();');"
// + "function flb() { if (event.willCommit)"
// + "{ console.println('in listbox action'); console.println(event.value); "
// + "if (lb.value == '-') formReady= false; else formReady=true; "
// + "if (formReady) this.getField('signatureField').display=display.visible; "
// + "else this.getField('signatureField').display=display.hidden; }}" +
// + " lb.value=event.value; ndf.value=event.value; }}" ;
// "f2.setAction('Keystroke', 'fft2();');function fft2() { if (!event.willCommit) { console.println(event.change); r2.value = event.change; }}";
PDFormFieldAdditionalActions fieldActions2 = new PDFormFieldAdditionalActions(); // usable only for .setK, not for .setU
//PDAnnotationAdditionalActions annotationActions = new PDAnnotationAdditionalActions();
PDActionJavaScript jsKeyStrokeAction = new PDActionJavaScript();
//jsKeystrokeAction.setAction("app.alert(\"On 'keystroke' action\")");
jsKeyStrokeAction.setAction(jsListBox2);
fieldActions2.setK(jsKeyStrokeAction);
legalForm.setActions(fieldActions2);
//widget3.setActions(annotationActions);*/
//PDAnnotationAdditionalActions annotationActions = new PDAnnotationAdditionalActions();
PDFormFieldAdditionalActions listboxAction2 = new PDFormFieldAdditionalActions();
// Add the annotation to the page
page.getAnnotations().add(widget3);
legalForm.setValue("-");
PDRectangle rect4 = new PDRectangle(50, 150, 200, 50);
PDAppearanceDictionary appearanceDictionary = new PDAppearanceDictionary();
PDAppearanceStream appearanceStream = new PDAppearanceStream(document);
appearanceStream.setBBox(rect4.createRetranslatedRectangle());
appearanceStream.setResources(resources);
appearanceDictionary.setNormalAppearance(appearanceStream);
PDPageContentStream contentStream = new PDPageContentStream(document, appearanceStream);
contentStream.setStrokingColor(Color.BLACK);
contentStream.setNonStrokingColor(Color.LIGHT_GRAY);
contentStream.setLineWidth(2);
contentStream.addRect(0, 0, rect4.getWidth(), rect4.getHeight());
contentStream.fill();
contentStream.moveTo(1 * rect4.getHeight() / 4, 1 * rect4.getHeight() / 4);
contentStream.lineTo(2 * rect4.getHeight() / 4, 3 * rect4.getHeight() / 4);
contentStream.moveTo(1 * rect4.getHeight() / 4, 3 * rect4.getHeight() / 4);
contentStream.lineTo(2 * rect4.getHeight() / 4, 1 * rect4.getHeight() / 4);
contentStream.moveTo(3 * rect4.getHeight() / 4, 1 * rect4.getHeight() / 4);
contentStream.lineTo(rect4.getWidth() - rect4.getHeight() / 4, 1 * rect4.getHeight() / 4);
contentStream.stroke();
contentStream.setNonStrokingColor(Color.DARK_GRAY);
contentStream.beginText();
contentStream.setFont(font, rect4.getHeight() / 5);
contentStream.newLineAtOffset(3 * rect4.getHeight() / 4, -font.getBoundingBox().getLowerLeftY() * rect4.getHeight() / 5000);
contentStream.showText("Customer");
contentStream.endText();
contentStream.close();
PDSignatureField signatureField = new PDSignatureField(pdAcroForm);
signatureField.setPartialName("signatureField");
PDAnnotationWidget widget4 = signatureField.getWidgets().get(0);
widget4.setAppearance(appearanceDictionary);
widget4.setRectangle(rect4);
widget4.setPage(page);
page.getAnnotations().add(widget4);
pdAcroForm.getFields().add(signatureField);
document.save("anacreditForm.pdf");
for (PDField pdField : pdAcroForm.getFields()) {
System.out.println(pdField.getFullyQualifiedName() + " " + pdField.getFieldType() + " " + pdField.getValueAsString());
}
document.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Adobe Reader apparently does reject signing attempts for documents in which by means of JavaScript an event handler has been changed.
Your code actually is an example why that is good: As soon as the original domicilation event handler is executed, it is set to 'fft();' but the code of fft() is only in the Adobe Reader's memory, not in the PDF anymore. Thus, a thereafter signed version of the PDF would behave differently as it would be missing that code.
As an aside, there is one unwanted closing round bracket in
+ "f.value=event.value) ; ndf.value= event.value;"
in jsListBox0.
i'm using iTextSharp to create a pdf document then add it as an attachment to send an email using SendGrid.
The code is working locally but after deploying the project in Azure this function stopped working for some reason. I tried to analyze the problem and i think that the document didn't fully created of attached due to the connection. I can't pin point the exact issue to solve it. Any opinions or discussion is appreciated.
Action:
public async Task<IActionResult> GeneratePDF(int? id, string recipientEmail)
{
//if id valid
if (id == null)
{
return NotFound();
}
var story = await _db.Stories.Include(s => s.Child).Include(s => s.Sentences).ThenInclude(s => s.Image).FirstOrDefaultAsync(s => s.Id == id);
if (story == null)
{
return NotFound();
}
var webRootPath = _hostingEnvironment.WebRootPath;
var path = Path.Combine(webRootPath, "dump"); //folder name
try
{
using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream())
{
iTextSharp.text.Document document = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 10, 10, 10, 10);
PdfWriter writer = PdfWriter.GetInstance(document, memoryStream);
document.Open();
string usedFont = Path.Combine(webRootPath + "\\fonts\\", "arial.TTF");
BaseFont bf = BaseFont.CreateFont(usedFont, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
iTextSharp.text.Font titleFont = new iTextSharp.text.Font(bf, 40);
iTextSharp.text.Font sentencesFont = new iTextSharp.text.Font(bf, 15);
iTextSharp.text.Font childNamewFont = new iTextSharp.text.Font(bf, 35);
PdfPTable T = new PdfPTable(1);
//Hide the table border
T.DefaultCell.BorderWidth = 0;
T.DefaultCell.HorizontalAlignment = 1;
T.DefaultCell.PaddingTop = 15;
T.DefaultCell.PaddingBottom = 15;
//Set RTL mode
T.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
//Add our text
if (story.Title != null)
{
T.AddCell(new iTextSharp.text.Paragraph(story.Title, titleFont));
}
if (story.Child != null)
{
if (story.Child.FirstName != null && story.Child.LastName != null)
{
T.AddCell(new iTextSharp.text.Phrase(story.Child.FirstName + story.Child.LastName, childNamewFont));
}
}
if (story.Sentences != null)
{
.................
}
document.Add(T);
writer.CloseStream = false;
document.Close();
byte[] bytes = memoryStream.ToArray();
var fileName = path + "\\PDF" + DateTime.Now.ToString("yyyyMMdd-HHMMss") + ".pdf";
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
fs.Write(bytes, 0, bytes.Length);
}
memoryStream.Position = 0;
memoryStream.Close();
//Send generated pdf as attchment
// Create the file attachment for this email message.
var attachment = Convert.ToBase64String(bytes);
var client = new SendGridClient(Options.SendGridKey);
var msg = new SendGridMessage();
msg.From = new EmailAddress(SD.DefaultEmail, SD.DefaultEmail);
msg.Subject = story.Title;
msg.PlainTextContent = "................";
msg.HtmlContent = "..................";
msg.AddTo(new EmailAddress(recipientEmail));
msg.AddAttachment("Story.pdf", attachment);
try
{
await client.SendEmailAsync(msg);
}
catch (Exception ex)
{
Console.WriteLine("{0} First exception caught.", ex);
}
//Remove form root
if (System.IO.File.Exists(fileName))
{
System.IO.File.Delete(fileName);
}
}
}
catch (FileNotFoundException e)
{
Console.WriteLine($"The file was not found: '{e}'");
}
catch (DirectoryNotFoundException e)
{
Console.WriteLine($"The directory was not found: '{e}'");
}
catch (IOException e)
{
Console.WriteLine($"The file could not be opened: '{e}'");
}
return RedirectToAction("Details", new { id = id });
}
try to edit usedfont variable as bellow :
var usedfont = Path.Combine(webRootPath ,#"\fonts\arial.TTF")
It turns out that the problem is far from iTextSharp. I did a remote debugging from this article.
Two parts of the code was causing the problem.
First, for some reason the folder "dump" was not created on Azure wwwroot folder while locally it is. so, i added these lines:
var webRootPath = _hostingEnvironment.WebRootPath;
var path = Path.Combine(webRootPath, "dump");
if (!Directory.Exists(path)) //Here
Directory.CreateDirectory(path);
Second, after debugging it shows that creating the file was failing every time. I replaced the following lines:
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
fs.Write(bytes, 0, bytes.Length);
}
memoryStream.Position = 0;
memoryStream.Close();
With:
using (FileStream fs = new FileStream(fileName, FileMode.Create))
using (var binaryWriter = new BinaryWriter(fs))
{
binaryWriter.Write(bytes, 0, bytes.Length);
binaryWriter.Close();
}
memoryStream.Close();
Hope this post helps someone.
I have an application that generates PDFs using the MigraDoc framework, however I have a requirement to add in a text driven watermark. I have found some examples of this being done using PDF Sharp here, however I just cant seem t be able to figure out how this will integrate with my Migradoc Document() object I am rendering.
I have the following code:
public byte[] render()
{
PdfDocument document = new PdfDocument();
CreateWaterMarks(document);
// *****************************
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = this.document;
renderer.RenderDocument();
byte[] pdfContents = null;
using (MemoryStream stream = new MemoryStream())
{
renderer.PdfDocument.Save(stream, true);
pdfContents = stream.ToArray();
}
return pdfContents;
}
This method is what is called to render the MigraDoc document and pass it out as a byte array. The second line of code in here calls the following method which is not doing what I am looking for:
void CreateWaterMarks(PdfDocument document)
{
PdfPage page = document.AddPage();
Document doc = this.document;
MigraDoc.Rendering.DocumentRenderer docRenderer = new DocumentRenderer(doc);
docRenderer.PrepareDocument();
XRect A4Rect = new XRect(0, 0, pageActiveWidth, pageActiveHeight);
int pageCount = docRenderer.FormattedDocument.PageCount;
for (int idx = 0; idx < pageCount; idx++)
{
XFont font = new XFont("Verdana", 13, XFontStyle.Bold);
XGraphics gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
XSize size = gfx.MeasureString("Watermark", font);
gfx.TranslateTransform(pageActiveWidth / 2, pageActiveHeight / 2);
gfx.RotateTransform(-Math.Atan(pageActiveHeight / pageActiveWidth) * 180 / Math.PI);
gfx.TranslateTransform(-pageActiveWidth / 2, -pageActiveHeight / 2);
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Near;
format.LineAlignment = XLineAlignment.Near;
XBrush brush = new XSolidBrush(XColor.FromArgb(128, 255, 0, 0));
gfx.DrawString("Watermark", font, brush, new XPoint((pageActiveWidth - size.Width) / 2, (pageActiveHeight - size.Height) / 2), format);
docRenderer.RenderPage(gfx, idx + 1);
}
}
I was hoping that this would magically make these PDFSharp watermarks appear but alas I get nothing!
I have this working using the following code:
public byte[] render()
{
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = this.document;
renderer.RenderDocument();
renderer.PrepareRenderPages();
CreateWatermarks(renderer);
byte[] pdfContents = null;
using (MemoryStream stream = new MemoryStream())
{
renderer.PdfDocument.Save(stream, true);
pdfContents = stream.ToArray();
}
return pdfContents;
}
private void CreateWatermarks(PdfDocumentRenderer renderer)
{
int pages = renderer.DocumentRenderer.FormattedDocument.PageCount;
for (int i = 0; i < pages; ++i)
{
var page = renderer.PdfDocument.Pages[i];
XFont font = new XFont("Verdana", 27, XFontStyle.Bold);
XGraphics gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
XSize size = gfx.MeasureString("Watermark", font);
gfx.TranslateTransform(pageActiveWidth / 2, pageActiveHeight / 2);
gfx.RotateTransform(-Math.Atan(pageActiveHeight / pageActiveWidth) * 180 / Math.PI);
gfx.TranslateTransform(-pageActiveWidth / 2, -pageActiveHeight / 2);
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Near;
format.LineAlignment = XLineAlignment.Near;
XBrush brush = new XSolidBrush(XColor.FromArgb(128, 255, 0, 0));
gfx.DrawString("Watermark", font, brush, new XPoint((pageActiveWidth - size.Width) / 2, (pageActiveHeight - size.Height) / 2), format);
}
}
I found many samples on the web, one of these:
var oldFile = #"C:\Users\XXX\Downloads\3921B2014901_2014_7346.pdf";
var newFile = #"C:\Users\XXX\Downloads\new\3921B2014901_2014_7346.pdf";
RandomAccessFileOrArray raf = new RandomAccessFileOrArray(oldFile);
PdfReader reader = new PdfReader(raf, null);
using (FileStream fs = new FileStream(newFile, FileMode.Create))
{
PdfStamper stamper = new PdfStamper(reader, fs, PdfWriter.VERSION_1_5);
PdfWriter writer = stamper.Writer;
writer.SetPdfVersion(PdfWriter.PDF_VERSION_1_5);
writer.CompressionLevel = PdfStream.BEST_COMPRESSION;
for (int i = 1; i <= reader.NumberOfPages; i++)
{
reader.SetPageContent(i, reader.GetPageContent(i), PdfStream.BEST_COMPRESSION, true);
}
stamper.SetFullCompression();
stamper.Close();
}
reader.Close();
raf.Close();
The original file is 2.75Mb and the resulting new file is 2.77Mb. Why?
I tried online converters and they reduce the same file to 500Kb. How can I achieve the same result?
protected void btnCompressPdf_click(object sender, EventArgs e)
{
string[] filename= Directory.GetFiles(input.Text, ".jpg");
string outputPath = MyDirectory;
if (!System.IO.Directory.Exists(MyDirectory))
System.IO.Directory.CreateDirectory(MyDirectory);
foreach (string filename in files)
{
ImageCollection images = new ImageCollection();
images.Add(filename);
String pdfName = Path.GetFileNameWithoutExtension(file);
for (int pageNumber = 0; pageNumber < images.Count; pageNumber++)
{
images[pageNumber].Save(MyDirectory + "\\" + pageNumber.ToString() + ".jpg");
}
string[] files1 = System.IO.Directory.GetFiles(MyDirectory, ".jpg");
iTextSharp.text.Document myDocument = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 0, 0, 0, 0);
//PdfWriter.GetInstance(myDocument, new System.IO.FileStream(uxOutput.Text + "\\" + pdfName + ".pdf", System.IO.FileMode.Create));
PdfWriter writer = PdfWriter.GetInstance(myDocument, new System.IO.FileStream(Output.Text + "\\" + pdfName + ".pdf", System.IO.FileMode.Create));
writer.SetPdfVersion(PdfWriter.PDF_VERSION_1_5);
writer.CompressionLevel = PdfStream.BEST_COMPRESSION;
writer.SetFullCompression();
for (int i = 0; i <= files1.Length - 1; i++)
{
if (myDocument != null)
{
myDocument.Open();
AddImageToPDF(myDocument, MyDirectory + "\\" + (i).ToString() + ".jpg");
}
}
myDocument.Close();
myDocument = null;
System.IO.File.Delete(MyDirectory + "\\" + ".jpg");
}
}
I have 3 pdfs templates that i Fill out and save to a memorystream them merge them together into 1 pdf into a memorystream. The resulting merged pdf is non flattenned. I tried reading the merged pdf and flattening it but it say "pdf header signature not found". Is there a way to flattened merged pdf from a memorystream.
this is what I tried so far without success.
var mergedPdf = MergePDFs(AllPdfs);
MemoryStream flattenedMergedPdf = new MemoryStream();
PdfReader Finalpdf = new PdfReader(mergedPdf);
PdfStamper StampFinalMerged = new PdfStamper(Finalpdf,flattenedMergedPdf);
StampFinalMerged.FormFlattening=true;
return flattenedMergedPdf;
the method i use to merge the pdfs(found on SO) is below:
public MemoryStream MergePDFs(List<byte[]> pdfFiles)
{
if (pdfFiles.Count > 1)
{
PdfReader finalPdf;
Document pdfContainer;
PdfCopy pdfCopy;
MemoryStream msFinalPdf = new MemoryStream();
finalPdf = new PdfReader(pdfFiles[0]);
pdfContainer = new Document();
pdfCopy = new PdfSmartCopy(pdfContainer, msFinalPdf);
pdfContainer.Open();
for (int k = 0; k < pdfFiles.Count; k++)
{
finalPdf = new PdfReader(pdfFiles[k]);
for (int i = 1; i < finalPdf.NumberOfPages + 1; i++)
{
((PdfSmartCopy)pdfCopy).AddPage(pdfCopy.GetImportedPage(finalPdf, i));
}
pdfCopy.FreeReader(finalPdf);
}
//tried this here but no success
// PdfReader FinalRead = new PdfReader(finalPdf);
//MemoryStream FinalMS = new MemoryStream();
//var finalStamper = new PdfStamper(FinalRead, FinalMS);
//finalStamper.FormFlattening = true;
pdfCopy.CloseStream = false;
pdfCopy.Close();
finalPdf.Close();
//return FinalMS
return msFinalPdf;
}
Any help will be much appreciated. Thanks
You can try another approach to flatten PDF templates first then merge them into a final PDF file:
string newFile = "... path to the merged pdf file ...";
string[] pdfTemplates = new string[3];
string pdfTemplates[0] = "... path to the 1st pdf template ...";
string pdfTemplates[1] = "... path to the 2nd pdf template ...";
string pdfTemplates[2] = "... path to the 3rd pdf template ...";
string[] pdfFiles = new string[3];
string pdfFiles[0] = "... path to the 1st temp pdf file ...";
string pdfFiles[1] = "... path to the 2nd temp pdf file ...";
string pdfFiles[2] = "... path to the 3rd temp pdf file ...";
for (int i = 0; i < 3; i++)
{
PdfReader pdfReader = new PdfReader(pdfTemplates[i]);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(pdfFiles[i], FileMode.Create));
pdfStamper.FormFlattening = true;
pdfStamper.Close();
}
MergeFiles(newFile, pdfFiles);
for (int i = 0; i < 3; i++)
{
FileInfo fi = new FileInfo(pdfFiles[i]);
fi.Delete();
}
private void MergeFiles(string destinationFile, string[] sourceFiles)
{
try
{
int f = 0;
PdfReader reader = new PdfReader(sourceFiles[f]);
int n = reader.NumberOfPages;
Document document = new Document(reader.GetPageSizeWithRotation(1));
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationFile, FileMode.Create));
document.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page;
int rotation;
while (f < sourceFiles.Length)
{
int i = 0;
while (i < n)
{
i++;
document.SetPageSize(reader.GetPageSizeWithRotation(i));
document.NewPage();
page = writer.GetImportedPage(reader, i);
rotation = reader.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
}
f++;
if (f < sourceFiles.Length)
{
reader = new PdfReader(sourceFiles[f]);
n = reader.NumberOfPages;
}
}
document.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}