简体   繁体   中英

C# PDF Sharp position in document

Hi I am using PDF sharp to print user input onto positions in a template document.

The data (fields) are collected from user (web page) and written at appropriate positions on the document using drawstring method.

Currently I am finding the Pixel position of each templated field in each page by trial and error .It would be much easier if there is a way to determine pixel position of each field in pdf page.

Any suggestion would be most helpful.

thanks

I had the same issue as you, josephj1989, and I found what I believe to be our answer.

According to this page in the PDFSharp documentation,

The current implementation of PDFsharp has only one layout of the graphics context. The origin (0, 0) is top left and coordinates grow right and down. The unit of measure is always point (1/72 inch).

So, say I want to draw an image 3 inches from the left and 7.5 inches from the top of an 8.5 x 11 page, then I would do something like this:

PdfDocument document = GetBlankPdfDocument();
PdfPage myPage = document.AddPage();
myPage.Orientation = PdfSharp.PageOrientation.Portrait;
myPage.Width = XUnit.FromInch(8.5);
myPage.Height = XUnit.FromInch(11);
XImage myImage = GetSampleImage();

double myX = 3 * 72;
double myY = 7.5 * 72;
double someWidth = 126;
double someHeight = 36;

XGraphics gfx = XGraphics.FromPdfPage(myPage);
gfx.DrawImage(myBarcode, myX, myY, someWidth, someHeight);

I tested this out myself with a barcode image, and I found that when you use their formula for measuring positioning, you can get a level of precision at, well, 1/72 of an inch. That's not bad.

So, at this point, it'd be good to create some kind of encapsulation for such measurements so that we're focused mostly on the task at hand and not the details of conversion.

public static double GetCoordinateFromInch(double inches)
{
  return inches * 72;
}

We could go on to make other helpers in this way...

public static double GetCoordinateFromCentimeter(double centimeters)
{
  return centimeters * 0.39370 * 72;
}

With such helper methods, we could do this with the previous sample code:

double myX = GetCoordinateFromInch(3);
double myY = GetCoordinateFromInch(7.5);
double someWidth = 126;
double someHeight = 36;

XGraphics gfx = XGraphics.FromPdfPage(myPage);
gfx.DrawImage(myBarcode, myX, myY, someWidth, someHeight);

I hope this is helpful. I'm sure you will write cleaner code than what is in my example. Additionally, there are probably much smarter ways to streamline this process, but I just wanted to put something here that would make immediate use of what we saw in the documentation.

Happy PDF Rendering!

When I used PDF Sharp, my approach was to make use the XUnit struct and to reference the top left point of the document as my starting point for X/Y positions.

Obviously referencing the top left point of the document (0,0) for every element on a PdfPage will get messy. To combat this, I used the XRect class to create rectangles for elements to sit within. Once the XRect is drawn onto the page, you are then able to reference the X/Y position of the rectange via the XRect's properties. Then with some basic maths using those coordinates and the width/height of the XRect, you should be able to calculate the coordinates for the position of the next element you want to add to the PdfPage.

Follow this code sample, I've provided a rough sketch of what the end result would be. The code is untested but is very heavily based on code in production right now.

// Create a new PDF document
PdfDocument document = new PdfDocument();

// Create an empty page with the default size/orientation
PdfPage page = document.AddPage();
page.Orientation = PageOrientation.Landscape;
page.Width = XUnit.FromMillimeter(300);
page.Height = XUnit.FromMillimeter(200);

// Get an XGraphics object for drawing
XGraphics gfx = XGraphics.FromPdfPage(page);

// Add the first rectangle
XUnit horizontalOffset = XUnit.FromMillimeter(5);
XUnit verticalOffset = XUnit.FromMillimeter(5);
XUnit columnWidth = XUnit.FromMillimeter(100);
XUnit columnHeight = page.Height - (2 * verticalOffset);
XRect columnRect = new XRect(horizontalOffset, verticalOffset, columnWidth, columnHeight);
gfx.DrawRectangle(XBrushes.Teal, columnRect);

// Insert an image inside the rectangle, referencing the Left and Top properties of the rectangle for image placement
XImage topLogo = XImage.FromFile(GetFilePath(@"content\img\pdfs\standard\logo-no-strapline.jpg")); // GetFilePath is a private method, not shown for brevity
gfx.DrawImage(topLogo,
    columnRect.Left + XUnit.FromMillimeter(5),
    columnRect.Top + XUnit.FromMillimeter(5),
    columnRect.Width - XUnit.FromMillimeter(10),
    XUnit.FromMillimeter(38));

And the output: 模拟渲染的输出

Lastly, I'm sure you're aware, but there's a good resource of PdfSharp samples here .

PDF files have no pixels and no pixel positions.
You can print PDF pages (use the "Actual size" size option) and measure positions with a ruler (this works pretty good with our printers).
Or you can use Adobe Acrobat to measure the positions of items on the PDF pages.

A bit of trial and error remains as you may have to give or take half a millimeter.
Depending on your ruler you can use XUnit.FromMillimeter or XUnit.FromInch to get the point positions for PDFsharp (but points are no pixels).

The current PDFsharp samples are here:
http://www.pdfsharp.net/wiki/PDFsharpSamples.ashx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM