I was in need of the ability to create a PDF Envelope, and hadn't found a good solution for doing so, so I thought that this might be of some interest.
We use PDFSharp, a free PDF document tool. It worked out pretty well. Here's the method for doing so. It will create a new pdf document, envelope sized, and center the address. GetAddress() is just a method used to retrieve the address from a DB. Just use
\n to newline the different lines in the address.
protected void DisplayPDFEnvelope()
{
try
{
PdfDocument document = new PdfDocument();
PdfPage pdfpage = new PdfPage();
XUnit pdfWidth = new XUnit(4.125, XGraphicsUnit.Inch);
XUnit pdfHeight = new XUnit(9.5, XGraphicsUnit.Inch);
pdfpage.Height = pdfHeight;
pdfpage.Width = pdfWidth;
pdfpage.Orientation = PageOrientation.Landscape;
XPdfFontOptions options = new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always);
document.AddPage(pdfpage);
// Create a font
XFont font = new XFont("ARIAL", 1, XFontStyle.Regular, options);
// Get an XGraphics object for drawing
XGraphics gfx = XGraphics.FromPdfPage(pdfpage, XGraphicsPdfPageOptions.Append);
string address = GetAddress();
// Get the size (in point) of the text
XSize size = gfx.MeasureString(address, font);
// Create a graphical path
XGraphicsPath path = new XGraphicsPath();
path.AddString(address, font.FontFamily, XFontStyle.Regular, 10,
new XPoint(345, 160), XStringFormats.Default);
// Create a dimmed pen and brush
XPen pen = new XPen(XColor.FromGrayScale(0), 0);
XBrush brush = new XSolidBrush();
// Stroke the outline of the path
gfx.DrawPath(pen, brush, path);
MemoryStream stream = new MemoryStream();
document.Save(stream, false);
Page.Response.Clear();
Page.Response.ContentType = "application/pdf";
Page.Response.AppendHeader("Content-Length", stream.Length.ToString());
Page.Response.AppendHeader("Content-Type", "application/pdf");
Page.Response.AppendHeader("Content-Disposition", "inline;filename=envelope.pdf");
Page.Response.BinaryWrite(stream.ToArray());
Page.Response.Flush();
stream.Close();
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
catch (Exception ex)
{
throw ex;
}
}
PDFSharp is good, so is iTextSharp, the Java port of iText, one of the first PDF libraries around.
Related
This was my code for itextsharp which worked ok. It displayed "Quote Only" in the middle of each page in a pdf file.
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(Server.MapPath(#"~\Content\WaterMarkQuoteOnly.png"));
PdfReader readerOriginalDoc = new PdfReader(File(all, "application/pdf").FileContents);
int n = readerOriginalDoc.NumberOfPages;
img.SetAbsolutePosition(0, 300);
PdfGState _state = new PdfGState()
{
FillOpacity = 0.1F,
StrokeOpacity = 0.1F
};
using (MemoryStream ms = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(readerOriginalDoc, ms, '\0', true))
{
for (int i = 1; i <= n; i++)
{
PdfContentByte content = stamper.GetOverContent(i);
content.SaveState();
content.SetGState(_state);
content.AddImage(img);
content.RestoreState();
}
}
//return ms.ToArray();
all = ms.GetBuffer();
}
This is my new itext 7 code, this also displays the watermark but the position is wrong. I was dismayed to see that you cant add an image to the canvas but you have to add ImageData when the position is being set on the image. The image is also way smaller and back to front.
var imagePath = Server.MapPath(#"~\Content\WaterMarkQuoteOnly.png");
var tranState = new iText.Kernel.Pdf.Extgstate.PdfExtGState();
tranState.SetFillOpacity(0.1f);
tranState.SetStrokeOpacity(0.1f);
ImageData myImageData = ImageDataFactory.Create(imagePath, false);
Image img = new Image(myImageData);
img.SetFixedPosition(0, 300);
var reader = new PdfReader(new MemoryStream(all));
var doc = new PdfDocument(reader);
int pages = doc.GetNumberOfPages();
using (var ms = new MemoryStream())
{
var writer = new PdfWriter(ms);
var newdoc = new PdfDocument(writer);
for (int i = 1; i <= pages; i++)
{
//get existing page
PdfPage page = doc.GetPage(i);
//copy page to new document
newdoc.AddPage(page.CopyTo(newdoc)); ;
//get our new page
PdfPage newpage = newdoc.GetPage(i);
Rectangle pageSize = newpage.GetPageSize();
//get canvas based on new page
var canvas = new PdfCanvas(newpage);
//write image data to new page
canvas.SaveState().SetExtGState(tranState);
canvas.AddImage(myImageData, pageSize, true);
canvas.RestoreState();
}
newdoc.Close();
all = ms.GetBuffer();
ms.Flush();
}
You are doing something strange with the PdfDocument objects, and you are also using the wrong AddImage() method.
I am not a C# developer, so I rewrote your example in Java. I took this PDF file:
And I took this image:
Then I added the image to the PDF file using transparency with the following result:
The code to do this, was really simple:
public void createPdf(String src, String dest) throws IOException {
PdfExtGState tranState = new PdfExtGState();
tranState.setFillOpacity(0.1f);
ImageData img = ImageDataFactory.create(IMG);
PdfReader reader = new PdfReader(src);
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdf = new PdfDocument(reader, writer);
for (int i = 1; i <= pdf.getNumberOfPages(); i++) {
PdfPage page = pdf.getPage(i);
PdfCanvas canvas = new PdfCanvas(page);
canvas.saveState().setExtGState(tranState);
canvas.addImage(img, 36, 600, false);
canvas.restoreState();
}
pdf.close();
}
For some reason, you created two PdfDocument instances. This isn't necessary. You also used the AddImage() method passing a Rectangle which resizes the image. Also make sure that you don't add the image as an inline image, because that bloats the file size.
I don't know which programming language you are using. For instance: I am not used to variables that are created using var such as var tranState. It should be very easy for you to adapt my Java code though. It's just a matter of changing lowercases into uppercases.
I was trying to generate a pdf from HTML which containing a table using PdfSharp and HTMLRenderer. The following shows the code.
pdf = PdfGenerator.GeneratePdf(html, PageSize.A3);
byte[] fileContents = null;
using (MemoryStream stream = new MemoryStream())
{
pdf.Save(stream, true);
fileContents = stream.ToArray();
return new FileStreamResult(new MemoryStream(fileContents.ToArray()), "application/pdf");
}
Is there any possibility for me to provide a custom size to the PDF and change the orientation of the page. I am using a memory stream to show the PDF directly on the browser display.
You can use the PdfGenerateConfig parameter of the GeneratePdf method to specify a custom page size using the ManualPageSize property.
Use the PageOrientation to get standard page sizes in landscape.
Code from comment:
var config = new PdfGenerateConfig();
config.PageOrientation = PageOrientation.Landscape;
config.ManualPageSize = new PdfSharp.Drawing.XSize(1080, 828);
pdf = PdfGenerator.GeneratePdf(html, config);
I just put this way:
var config = new PdfGenerateConfig()
{
MarginBottom = 100,
MarginLeft = 20,
MarginRight = 20,
MarginTop = 100,
PageSize = PageSize.A4
};
PdfDocument pdf = PdfGenerator.GeneratePdf(html, config);
If I'm not mistaken, PageSize.A3 is not an enum but Rectangle value. So instead of passing predefined Rectangle you can provide your own, for example:
new Rectangle(1191, 842) // for album A3
new Rectangle(842, 595) // for album A4
and so on...
i am a new to c# programming and i am doing a project that can capture the screen and attach it to a pdf,in my project i need to attach an screenshot of my desktop or application directly to PDF file, i know how to attached a image that has been saved in to the Hard Drive, in this case i used iTextsharp library. what i need to know is there a way to attach the image directly to PDF without saving the image to Hard Drive. till now I can capture my screen and save it to the hard drive. please direct me to a path, Thanx In Advance , code i used is bellow
this is the code i used to capture the screen
string pHotoTime = DateTime.Now.ToString("yyyy-MM-dd, HH mm ss");
Size s = Screen.PrimaryScreen.Bounds.Size;
Bitmap bmp = new Bitmap(s.Width, s.Height);
Graphics g = Graphics.FromImage(bmp);
g.CopyFromScreen(0, 0, 0, 90, s);
System.IO.Stream stream = new System.IO.MemoryStream();
bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
stream.Position = 0;
// later:
//bmp.Save(#"C:\Users\NiyNLK\Documents\TESTs\" + pHotoTime + ".jpg");
bmp.Save(#"C:\Users\NiyNLK\Documents\TESTs\MyImage.jpg");
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = bmp;
below code is used to attached the image
enter code here
iTextSharp.text.Rectangle r = new iTextSharp.text.Rectangle(400, 400);
var doc = new Document(r);
string path = #"c:\users\niynlk\documents\tests";
string Imagepath = #"C:\Users\NiyNLK\Documents\TESTs";
try
{
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(path + "/Images.pdf", FileMode.Create));
doc.Open();
doc.Add(new Paragraph("Image"));
Image img = Image.GetInstance(Imagepath + "/MyImage.jpg");
img.ScalePercent(25f);
doc.Add(img);
}
catch (Exception)
{
throw;
}
finally
{
doc.Close();
}
I am generating a PDF using iTextSharp and there is dynamic content in the middle of the page which is pushing the bottom part of my PdfPTable down too far. Sometimes even off the bottom of the page onto another page.
Would it be possible to position the bottom PdfPTable in a way that it would not get pushed down when the table above it needs more vertical space?
Here is my solution.
Views\Home\Index.cshtml:
<h2>Create PDF</h2>
#Html.ActionLink("Create the PDF", "CreatePDF", "Home")
</div>
HomeController.cs:
public ActionResult Index()
{
return View();
}
public FileStreamResult CreatePDF()
{
Stream fileStream = GeneratePDF();
HttpContext.Response.AddHeader("content-disposition", "inline; filename=MyPDF.pdf");
var fileStreamResult = new FileStreamResult(fileStream, "application/pdf");
return fileStreamResult;
}
private Stream GeneratePDF()
{
var rect = new Rectangle(288f, 144f);
var document = new Document(rect, 10, 10, 10, 10);
document.SetPageSize(PageSize.LETTER.Rotate());
MemoryStream memoryStream = new MemoryStream();
PdfWriter pdfWriter = PdfWriter.GetInstance(document, memoryStream);
document.Open();
////////////////////////
//Place Image in a Specific (Absolute) Location
////////////////////////
Image myImage = Image.GetInstance(Server.MapPath("../Content/BI_logo_0709.png"));
myImage.SetAbsolutePosition(45, 45);
//[dpi of page]/[dpi of image]*100=[scale percent]
//72 / 200 * 100 = 36%
//myImage.ScalePercent(36f);
myImage.ScalePercent(36f);
document.Add(myImage);
////////////////////////
//Place Text in a Specific (Absolute) Location
////////////////////////
//Create a table to hold everything
PdfPTable myTable = new PdfPTable(1);
myTable.TotalWidth = 200f;
myTable.LockedWidth = true;
//Create a paragraph with the text to be placed
BaseFont bfArialNarrow = BaseFont.CreateFont(Server.MapPath("../Content/ARIALN.ttf"), BaseFont.CP1252, BaseFont.EMBEDDED);
var basicSmaller = new Font(bfArialNarrow, 10);
var myString = "Hello World!" +
Environment.NewLine +
"Here is more text." +
Environment.NewLine +
"Have fun programming!";
var myParagraph = new Paragraph(myString, basicSmaller);
//Create a cell to hold the text aka paragraph
PdfPCell myCell = new PdfPCell(myParagraph);
myCell.Border = 0;
//Add the cell to the table
myTable.AddCell(myCell);
//Add the table to the document in a specific (absolute) location
myTable.WriteSelectedRows(0, -1, 550, 80, pdfWriter.DirectContent);
pdfWriter.CloseStream = false;
document.Close();
memoryStream.Position = 0;
return memoryStream;
}
is there any logic to get paragraph text from pdf file using itextsharp?i know pdf only supports run of texts and its hard to determine which runs of texts are related to which paragraph and also i know that there isn't any <p> tags or other tags to determine paragraph in pdf..However i have tried to get coordinate of runs of texts to build paragraph from its coordinate but with no luck :(.
my code snippet is here:
private StringBuilder result = new StringBuilder();
private Vector lastBaseLine;
//to store run of texts
public List<string> strings = new List<String>();
//to store run of texts Coordinate (Y coordinate)
public List<float> baselines = new List<float>();
public void RenderText(iTextSharp.text.pdf.parser.TextRenderInfo renderInfo)
{
Vector curBaseline = renderInfo.GetBaseline().GetStartPoint();
if ((this.lastBaseLine != null) && (curBaseline[Vector.I2] != lastBaseLine[Vector.I2]))
{
if ((!string.IsNullOrEmpty(this.result.ToString())))
{
this.baselines.Add(this.lastBaseLine[Vector.I2]);
this.strings.Add(this.result.ToString());
}
result = new StringBuilder();
}
this.result.Append(renderInfo.GetText());
this.lastBaseLine = curBaseline;
}
Do any body have any logic related to this issue??
using (MemoryStream ms = new MemoryStream())
{
Document document = new Document(PageSize.A4, 25, 25, 30, 30);
PdfWriter writer = PdfWriter.GetInstance(document, ms);
document.Open();
document.Add(new Paragraph("Hello World"));
document.Close();
writer.Close();
Response.ContentType = "pdf/application";
Response.AddHeader("content-disposition",
"attachment;filename=First PDF document.pdf");
Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
}
here are some samples which ll help you on this....
This is may not be exactly your looking for, but it may help you..