Create footer with page number not displayed using Document object of EvoPdf - footer

I have a pdf file that converted from html by EvoPdf HtmlToPdfConverter. I read the file bytes by evopdf Document Class and add footer element to it. after saving the bytes - it's displaying inline webBrowser.
the footer with page number isn't displayed.
This is my code:
Document pdfDoc = new Document("myFilePath.pdf");
//create the footer element
TextElement footerText = new TextElement(0, 30, "Page &p; of &P; ",
new System.Drawing.Font( new System.Drawing.FontFamily("Arial"), 10, System.Drawing.GraphicsUnit.Point));
footerText.EmbedSysFont = true;
footerText.TextAlign = HorizontalTextAlign.Right;
pdfDoc.AddFooterTemplate(50);
pdfDoc.Footer.AddElement(footerText);
byte[] outBuffer = pdfDoc.Save();
pdfDoc.Close();
//...
If I add the footer element to the htmlToPdfConverter it displayed well.
how can I display it?
Thanks.

I have also run into the same situation. Basically, I wanted to add header and footer to existing PDFs without using htmltopdfconverter.
Here is the solution with a few tweaks to your existing code:
//Create a blank document.
Document MergeDocument = new Document();
Document pdfDoc = new Document("myFilePath.pdf");
//Merged n number of existing PDFs to newly created document.
MergedDocument.AppendDocument(pdfDoc, true, true, true);
//create the footer element
TextElement footerText = new TextElement(0, 30, "Page &p; of &P; ",
new System.Drawing.Font( new System.Drawing.FontFamily("Arial"), 10, System.Drawing.GraphicsUnit.Point));
footerText.EmbedSysFont = true;
footerText.TextAlign = HorizontalTextAlign.Right;
//Apply footer to the newly created document after all documents appended.
MergeDocument.AddFooterTemplate(50);
MergeDocument.Footer.AddElement(footerText);
byte[] outBuffer = MergeDocument.Save();
MergeDocument.Close();

In order to apply headers and footer on existing PDF documents you have to create an empty Document object, define the header and footer and then append the external PDF documents using the method Document.AppendDocument(Document doc, bool enableHeaderAndFooter, bool drawHeaderOnFirstPage, bool drawFooterOnFirstPage).
Below you can find a complete example for this. You can also find an online demo at Add Header and Footer in External PDF
public void protected void createPdfButton_Click(object sender, EventArgs e)
{
// Create a PDF document
Document pdfDocument = new Document();
// Add a PDF page to PDF document
PdfPage pdfPage = pdfDocument.AddPage();
try
{
// Add a default document header
AddHeader(pdfDocument, true);
// Add a default document footer
AddFooter(pdfDocument, true, true);
// Create a HTML to PDF element to add to document
HtmlToPdfElement htmlToPdfElement = new HtmlToPdfElement(0, 0, urlTextBox.Text);
// Optionally set a delay before conversion to allow asynchonous scripts to finish
htmlToPdfElement.ConversionDelay = 2;
// Add HTML to PDF element to document
pdfPage.AddElement(htmlToPdfElement);
// Automatically close the external PDF documents after the final document is saved
pdfDocument.AutoCloseAppendedDocs = true;
// Insert an external PDF document in the beginning of the final PDF document
string pdfFileBefore = Server.MapPath("~/DemoAppFiles/Input/PDF_Files/Merge_Before_Conversion.pdf");
Document startExternalDocument = new Document(pdfFileBefore);
pdfDocument.InsertDocument(0, startExternalDocument, addHeaderFooterInInsertedPdfCheckBox.Checked,
showHeaderInFirstPageCheckBox.Checked, showFooterInFirstPageCheckBox.Checked);
// Append an external PDF document at the end of the final PDF document
string pdfFileAfter = Server.MapPath("~/DemoAppFiles/Input/PDF_Files/Merge_After_Conversion.pdf");
Document endExternalDocument = new Document(pdfFileAfter);
pdfDocument.AppendDocument(endExternalDocument, addHeaderFooterInAppendedPdfCheckBox.Checked, true, true);
// Save the PDF document in a memory buffer
byte[] outPdfBuffer = pdfDocument.Save();
// Send the PDF as response to browser
// Set response content type
Response.AddHeader("Content-Type", "application/pdf");
// Instruct the browser to open the PDF file as an attachment or inline
Response.AddHeader("Content-Disposition", String.Format("attachment; filename=Header_Footer_in_External_PDF.pdf; size={0}", outPdfBuffer.Length.ToString()));
// Write the PDF document buffer to HTTP response
Response.BinaryWrite(outPdfBuffer);
// End the HTTP response and stop the current page processing
Response.End();
}
finally
{
// Close the PDF document
pdfDocument.Close();
}
}
/// <summary>
/// Add a header to document
/// </summary>
/// <param name="pdfDocument">The PDF document object</param>
/// <param name="drawHeaderLine">A flag indicating if a line should be drawn at the bottom of the header</param>
private void AddHeader(Document pdfDocument, bool drawHeaderLine)
{
string headerHtmlUrl = Server.MapPath("~/DemoAppFiles/Input/HTML_Files/Header_HTML.html");
// Create the document footer template
pdfDocument.AddHeaderTemplate(60);
// Create a HTML element to be added in header
HtmlToPdfElement headerHtml = new HtmlToPdfElement(headerHtmlUrl);
// Set the HTML element to fit the container height
headerHtml.FitHeight = true;
// Add HTML element to header
pdfDocument.Header.AddElement(headerHtml);
if (drawHeaderLine)
{
float headerWidth = pdfDocument.Header.Width;
float headerHeight = pdfDocument.Header.Height;
// Create a line element for the bottom of the header
LineElement headerLine = new LineElement(0, headerHeight - 1, headerWidth, headerHeight - 1);
// Set line color
headerLine.ForeColor = Color.Gray;
// Add line element to the bottom of the header
pdfDocument.Header.AddElement(headerLine);
}
}
/// <summary>
/// Add a footer to document
/// </summary>
/// <param name="pdfDocument">The PDF document object</param>
/// <param name="addPageNumbers">A flag indicating if the page numbering is present in footer</param>
/// <param name="drawFooterLine">A flag indicating if a line should be drawn at the top of the footer</param>
private void AddFooter(Document pdfDocument, bool addPageNumbers, bool drawFooterLine)
{
string footerHtmlUrl = Server.MapPath("~/DemoAppFiles/Input/HTML_Files/Footer_HTML.html");
// Create the document footer template
pdfDocument.AddFooterTemplate(60);
// Set footer background color
RectangleElement backColorRectangle = new RectangleElement(0, 0, pdfDocument.Footer.Width, pdfDocument.Footer.Height);
backColorRectangle.BackColor = Color.WhiteSmoke;
pdfDocument.Footer.AddElement(backColorRectangle);
// Create a HTML element to be added in footer
HtmlToPdfElement footerHtml = new HtmlToPdfElement(footerHtmlUrl);
// Set the HTML element to fit the container height
footerHtml.FitHeight = true;
// Add HTML element to footer
pdfDocument.Footer.AddElement(footerHtml);
// Add page numbering
if (addPageNumbers)
{
// Create a text element with page numbering place holders &p; and & P;
TextElement footerText = new TextElement(0, 30, "Page &p; of &P; ",
new System.Drawing.Font(new System.Drawing.FontFamily("Times New Roman"), 10, System.Drawing.GraphicsUnit.Point));
// Align the text at the right of the footer
footerText.TextAlign = HorizontalTextAlign.Right;
// Set page numbering text color
footerText.ForeColor = Color.Navy;
// Embed the text element font in PDF
footerText.EmbedSysFont = true;
// Add the text element to footer
pdfDocument.Footer.AddElement(footerText);
}
if (drawFooterLine)
{
float footerWidth = pdfDocument.Footer.Width;
// Create a line element for the top of the footer
LineElement footerLine = new LineElement(0, 0, footerWidth, 0);
// Set line color
footerLine.ForeColor = Color.Gray;
// Add line element to the bottom of the footer
pdfDocument.Footer.AddElement(footerLine);
}
}

Related

How to get the total page number in iText7 when adding that info to the document footer?

In iTextSharp, we can override the OnCloseDocument() event and add the Page # of #total on the footer of the document. However, the PdfDocument does not have this document close event anymore. Since we cannot determine the total number of pages while adding new pages, how can we determine this total number and put it on the footer while generating the document?
I've seen some suggestions with brute force method: after the PDF document is generated and before it's flushed, use PdfReader to read through it to get the total number before updating the footer. Is this the only way? Is there any better way of doing this?
Thanks.
That is one of the ways of doing it.
Another way of doing that is described in this code sample:
protected void manipulatePdf(String dest) throws Exception {
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
Document doc = new Document(pdfDoc);
int numberOfPages = pdfDoc.getNumberOfPages();
for (int i = 1; i <= numberOfPages; i++) {
// Write aligned text to the specified by parameters point
doc.showTextAligned(new Paragraph(String.format("page %s of %s", i, numberOfPages)),
559, 806, i, TextAlignment.RIGHT, VerticalAlignment.TOP, 0);
}
doc.close();
}
In that code sample you would add the footer after creating and flushing the PDF. This is a very simple and easy way of doing this request.
Another way of doing that is with IEventHandler.
PdfWriter writer = new PdfWriter(myMemoryStream);
pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, new TextFooterEventHandler(document));
then :
public class TextFooterEventHandler : IEventHandler
{
protected Document doc;
public TextFooterEventHandler(Document doc)
{
this.doc = doc;
}
public void HandleEvent(Event currentEvent)
{
var docEvent = (PdfDocumentEvent)currentEvent;
var pageSize = docEvent.GetPage().GetPageSize();
var fonts = new FontHelper();
var font = fonts.Label();
int pageNum = docEvent.GetDocument().GetPageNumber(docEvent.GetPage());
float coordX = ((pageSize.GetLeft() + doc.GetLeftMargin())
+ (pageSize.GetRight() - doc.GetRightMargin())) / 2;
float footerY = doc.GetBottomMargin();
Canvas canvas = new Canvas(docEvent.GetPage(), pageSize);
canvas
.SetFont(font)
.SetFontSize(8)
.ShowTextAligned((("Page " + pageNum.ToString())), coordX + 250, footerY - 40, TextAlignment.CENTER)
.SetLineThrough()
.Close();
}
}

TCPDF Header and Top Margin on fist page only then no header and different top margin on remaining pages

I am using tcpdf to generate a pdf. I only want the header to appear on the first page and have it so that it does not appear on the remaining pages. However, I would like the top margin of the remaining pages shifted up since there is no header on those pages.
I'm using MYPDF to extend TCPDF to customize the header to only show on the first page.
// Extend the TCPDF class to create custom Header and Footer
class MYPDF extends TCPDF {
//Page header
public function Header() {
if (count($this->pages) === 1) { // Do this only on the first page
$html .= 'header text';
}
$this->writeHTML($html, true, false, false, false, '');
}
}
// create new PDF document
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, 'LETTER', true, 'UTF-8', false);
// set document information
$pdf->SetCreator(PDF_CREATOR);
// set default header data
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE, PDF_HEADER_STRING);
// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
// set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, 25, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(10);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
// set auto page breaks
$pdf->SetAutoPageBreak(TRUE, 20);
// set image scale factor
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
// set some language-dependent strings (optional)
if (#file_exists(dirname(__FILE__).'/lang/eng.php')) {
require_once(dirname(__FILE__).'/lang/eng.php');
$pdf->setLanguageArray($l);
}
// ---------------------------------------------------------
// set font
$pdf->SetFont('droidsansfallback', '', 10);
// add a page
$pdf->AddPage();
$pdf->resetColumns();
$pdf->setEqualColumns(3, 57); // KEY PART - number of cols and width
$pdf->selectColumn();
$content = '';
$content .= '
<table cellspacing="0" cellpadding="3">
';
$content .= fetch_data();
$content .= '</table>';
$pdf->writeHTML($content);
$pdf->Output('file.pdf', 'I');
Something like this worked for me:
public function Header() {
if ($this->page == 1) {
$html .= 'header text';
$this->writeHTML($html, true, false, false, false, '');
} else {
$this->SetMargins(PDF_MARGIN_LEFT, 10, PDF_MARGIN_RIGHT);
}
}
Only write the header HTML on the first page, then change the margins for the other pages.

Converting PDF with form to PDF without form

i have a PDF template containing a form. At present, I'm using itextpdf to fill the form fields, and save the resulting pdf.
Is there a way to get completeley rid of the pdf form (i.e. converting the pdf to a form-free pdf containing the inserted data)?
You need to set setFormFlattening to true on your PdfStamper object.
Code is from their documentation:
for (Movie movie : PojoFactory.getMovies(connection)) {
if (count == 0) {
baos = new ByteArrayOutputStream();
reader = new PdfReader(RESOURCE);
stamper = new PdfStamper(reader, baos);
stamper.setFormFlattening(true);
form = stamper.getAcroFields();
}
count++;
}
if (count > 0) {
stamper.close();
reader = new PdfReader(baos.toByteArray());
copy.addPage(copy.getImportedPage(reader, 1));
}
That way the form will be flattened when you close your PdfStamper.

Streaming Word Doc in OpenXML SDK using ASP.NET MVC 4 gets corrupt document

I am trying to do this on ASP.NET MVC 4:
MemoryStream mem = new MemoryStream();
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Create(mem, DocumentFormat.OpenXml.WordprocessingDocumentType.Document, true))
{
// instantiate the members of the hierarchy
Document doc = new Document();
Body body = new Body();
Paragraph para = new Paragraph();
Run run = new Run();
Text text = new Text() { Text = "The OpenXML SDK rocks!" };
// put the hierarchy together
run.Append(text);
para.Append(run);
body.Append(para);
doc.Append(body);
//wordDoc.Close();
///wordDoc.Save();
}
return File(mem.ToArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "ABC.docx");
However the ABC.docx opens as corrupted and it wouldn't open even after fixing it.
Any ideas?
Linked Qs:
Streaming In Memory Word Document using OpenXML SDK w/ASP.NET results in "corrupt" document
Apparently the problem comes from missing this 2 lines:
wordDoc.AddMainDocumentPart();
wordDoc.MainDocumentPart.Document = doc;
Updated the code to below and it now works flawlessly, even without any extra flushing, etc necessary.
MemoryStream mem = new MemoryStream();
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Create(mem, DocumentFormat.OpenXml.WordprocessingDocumentType.Document, true))
{
wordDoc.AddMainDocumentPart();
// instantiate the members of the hierarchy
Document doc = new Document();
Body body = new Body();
Paragraph para = new Paragraph();
Run run = new Run();
Text text = new Text() { Text = "The OpenXML SDK rocks!" };
// put the hierarchy together
run.Append(text);
para.Append(run);
body.Append(para);
doc.Append(body);
wordDoc.MainDocumentPart.Document = doc;
wordDoc.Close();
}
return File(mem.ToArray(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "ABC.docx");

Is there any way to display image in client browser without uploading it to server?

I am writing a simple "Book" create page in ASP.NET MVC. User can create book by filling title,year etc.. and selecting a cover image. When user press "Create" button Form sends image and data to Controller action called "Create" then I save image to disk and data to database.
But I want to display image when user select image by file dialog.To do this As far as I know I must upload image to server then display in client browser.But if a user cancels the "Create" operation after uploading image, the image will remain in the server's disk.So How can I deal with these temp images or Is there any way to display image in client browser without upload to server?
Due to security reasons, you will not be able to display the images to the users without uploading them to the server. Displaying images from file system is considered a security risk.
EDIT: To remove the unused images, you can create a thread to run a cleanup routine to which will delete them from the upload directory regularly.
Yes, using Silverlight, for example:
In Page.xaml:
<StackPanel x:Name="LayoutRoot" Background="White">
<Button x:Name="btn1" Content="Select image file">
<Image x:Name="img1">
</StackPanel>
and in Page.xaml.cs:
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
btn1.Click += new RoutedEventHandler(btn1_Click);
}
void btn1_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == true)
{
Stream s = ofd.File.OpenRead();
BitmapImage bi = new BitmapImage();
bi.SetSource(s);
img1.Source = bi;
s.Close();
}
}
}
Read more here.
Yes, you can using javascript
Javascript:
function showThumbnail(files){
for(var i=0;i<files.length;i++){
var file = files[i]
var imageType = /image.*/
if(!file.type.match(imageType)){
console.log("Not an Image");
continue;
}
var image = document.createElement("img");
var thumbnail = document.getElementById("thumbnail");
image.file = file;
thumbnail.appendChild(image)
var reader = new FileReader()
reader.onload = (function(aImg){
return function(e){
aImg.src = e.target.result;
};
}(image))
var ret = reader.readAsDataURL(file);
var canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
image.onload= function(){
ctx.drawImage(image,100,100)
}
}
}
var fileInput = document.getElementById("upload-image");
fileInput.addEventListener("change",function(e){
var files = this.files
showThumbnail(files)
},false)
HTML:
<input type="file" id="upload-image" multiple="multiple"></input>
<div id="thumbnail"></div>
You just need the input field and The div to display the thumbnail image, and on change for the input field will call showThumbnail function which will append img inside the "thumbnail" div.
You can do it with Simple javascript...
assign the selected image path.. to image tag prefixing the file://, n it works the way you want it to be

Resources