Where does bottom and right border come from in abcPdf - c#

Why I am getting border on bottom and right when rendering html using abcAdf.
PS I got professional license using (ABCpdf9-64.dll)
My process is to create page:
I use master / child layout template in mvc (works)
I point to this html using abcPdf to convert into pdf
Html rendered
When my html gets rendered (plain) format : each originating from its respective location.
<h1>Layout</h1>
<p>
content
</p>
C# code to render pdf
My code is as follows:
using (var pdf = new Doc())
{
pdf.HtmlOptions.Timeout = 600000;
pdf.HtmlOptions.AddTags = true;
pdf.Page = pdf.AddPage();
var id = pdf.AddImageUrl(url, true, 1024, true);
if (allowPaging)
{
while (true)
{
if (!pdf.Chainable(id))
{
break;
}
pdf.Page = pdf.AddPage();
id = pdf.AddImageToChain(id);
}
for (int i = 1; i <= pdf.PageCount; i++)
{
pdf.PageNumber = i;
pdf.Flatten();
}
////reset back to page 1 so the pdf starts displaying there
if (pdf.PageCount > 0)
{
pdf.PageNumber = 1;
}
}
return store(pdf);
}
Output
My text/html gets rendered ok but I get borders that I have not asked for.
Rendered output:
Please note the hairline in bottom of the image.

After hours of googling about setting margin in abcpdf, I found nothing and took it as a challenge to find it myself.
I tried experimenting with everything I found relevant in the abcpdf documentation and finally made a chart myself
for setting the margins. I have successfully implemented this in many situations. Hope this helps others.
Here is a code snippet that shows how to set margins-
string html; // my html content that should be shown in the pdf page
Doc pdf = new Doc();
// adjust the default rotation and save
double w = pdf.MediaBox.Width;
double h = pdf.MediaBox.Height;
double l = pdf.MediaBox.Left;
double b = pdf.MediaBox.Bottom;
// explicitly giving page size
pdf.MediaBox.String = "A4";
pdf.Transform.Rotate(90, l, b);
pdf.Transform.Translate(w, 0);
pdf.Rect.Width = h;
pdf.Rect.Height = w;
int theID1 = pdf.GetInfoInt(pdf.Root, "Pages");
pdf.SetInfo(theID1, "/Rotate", "90");
int theID;
pdf.Rect.String = "17 55 823 423";
theID = pdf.AddImageHtml(html.ToString()); //Writes the HTML image to PDF
Here is a picture that describes margin layout for some junk values. Here
20 suggests that your content starts 20 pixels away from left of your pdf page
770 suggests that your content ends 770 pixels away from left of your pdf page
75 suggests that your content starts 55 pixels above the bottom of your pdf page
600 suggests that your content ends 600 pixels above the bottom of your pdf page
In your case you have to add
pdf.Rect.String = "20 75 770 600"; // giving junk values
right before
var id = pdf.AddImageUrl(url, true, 1024, true);
NOTE: In this example I explicitly set landscape mode instead of portrait mode. But orientation doesn't matter for setting
margins.

Related

iText 7 C# creating a pdf from a template and adding text to it

I have a one page pdf template and need to create a new document with several pages. Each page needs to be as the first page of the template. Then i need to add text to each page. The pages are copied but the text is not added.
This is my code:
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(stream));
PdfDocument cover = new PdfDocument(new PdfReader(templatePath));
//First copy the pages
var totalPages=5;
var coverPage = cover.GetPage(1);
for (int i = 0; i < totalPages; i++)
{
//If i do it to a blank page the text is visible
//pdfDoc.AddNewPage();
//I have tried both methods:
pdfDoc.AddPage(coverPage.CopyTo(pdfDoc));
//cover.CopyPagesTo(1, 1, pdfDoc);
}
//Now i try to add text
Document doc = new Document(pdfDoc);
var font = PdfFontFactory.CreateFont(fontPath);
for (int i = 1; i <= totalPages; i++)
{
//Edited
Rectangle pagesize = pdfDoc.GetPage(i).GetPageSize();
doc.ShowTextAligned(new Paragraph("HEADER").SetFont(font).SetFontSize(22), pagesize.GetLeft(), pagesize.GetBottom(), i, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);
//doc.ShowTextAligned(new Paragraph("HEADER").SetFont(font), 100, 700, i, TextAlignment.CENTER, VerticalAlignment.TOP, 0);
}
doc.Close();
cover.Close();
pdfDoc.Close();
I have tried this options:
Canvas instead of document with no result (see code below)
If i use the AddNewPage() and not the cover page, then the text is added to the blank page (both document and canvas methods).
If i open and write directly to the template document the text is visible but the size is very small and position of the text is different compared to 2)
This is the canvas code inside the for instruction:
var canvas = new PdfCanvas(pdfDoc.GetPage(i));
canvas.BeginText()
.SetFontAndSize(font, 22) //Edited
.MoveText(100, 700)
.ShowText("HEADER")
.EndText();
//UPDATED
Following the solution contributed by #mkl, i have changed the way i add the pages:
var coverPage = cover.GetPage(1);
Rectangle coverSize = coverPage.GetPageSize();
for (int i = 0; i < totalPaginas; i++)
{
//Taken from this example: https://kb.itextpdf.com/home/it7kb/ebooks/itext-7-jump-start-tutorial-for-java/chapter-6-reusing-existing-pdf-documents
PdfPage page = pdfDoc.AddNewPage(PageSize.A4);
PdfCanvas canvas = new PdfCanvas(page);
AffineTransform transformationMatrix = AffineTransform.GetScaleInstance(
page.GetPageSize().GetWidth() / coverSize.GetWidth(),
page.GetPageSize().GetHeight() / coverSize.GetHeight());
canvas.ConcatMatrix(transformationMatrix);
var pageCopy = coverPage.CopyAsFormXObject(pdfDoc);
canvas.AddXObjectAt(pageCopy, 0, 0);
//pdfDoc.AddNewPage();
//pdfDoc.AddPage(coverPage.CopyTo(pdfDoc));
//cover.CopyPagesTo(1, 1, pdfDoc);
}
Now i can see the text added, but the font size is much smaller than if instead of copying i do "pdfDoc.AddNewPage()", why is it? i would like it to be the correct font size.
Your code works in my tests. Maybe (100,700) is outside of the visual page area, which would typically be the case if your template page does not have its lower left corner at (0,0).
This should put the text in the lower left corner:
Rectangle pagesize = pdfDoc.GetPage(i).GetPageSize();
doc.ShowTextAligned(new Paragraph("HEADER"), pagesize.GetLeft(),
pagesize.GetBottom(), i, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);
If that works, you can work from the pagesize rectangle to calculate the appropriate position for the text.
The solution to why the text dont appear is updated in my question at the bottom.
The reason why the coordinates dont match and the size is so small is the source template pdf that was exported with a very high px/inch for high level printing. Reducing it to 72ppp was the fix.

Merging PDFs with different orientations with iTextSharp

I have two PDF files with different orientations (first document is A4 format and the second A4 landscape).
I want to merge them but I need to preserve the original orientation of each page.
I tried with the rotation with this code:
float width = pdfImportedPage.Width;
float height = pdfImportedPage.Height;
if (width > height)
{
PdfDictionary pageDict = reader.GetPageN(documentPage);
pageDict.Put(PdfName.ROTATE, new PdfNumber(270));
}
After the rotation I call the AddPage method like this:
copy.AddPage(pdfImportedPage);
But the result is an A4 format document with the second part with the text that goes out of the page. For me is good if the text in the second part is horizontal but I need that also the orientation of the page will be as the original document (horizontal).
I'm using iTextSharp version 5.5.13.
I've just discovered that the problem was in another part of the code, after that, when I add the page number.
By the way, a good way to preserve the page orientation is to use the SetPageSize and the NewPage methods, like this piece of code:
for (int page = 1; page <= reader.NumberOfPages; page++)
{
copy.RotateContents = true;
doc.SetPageSize(reader.GetPageSizeWithRotation(page));
doc.NewPage();
importedPage = copy.GetImportedPage(reader, page);
copy.AddPage(importedPage);
}

How to convert an autocad file to a pdf file with clear view?

I'm working on an asp.net project that converts autocad file .dwg to PDF.
I use the following code to do so :
using (var image = Aspose.CAD.Image.Load(filePath))
{
// create an instance of CadRasterizationOptions & set resultant page size
var rasterizationOptions = new Aspose.CAD.ImageOptions.CadRasterizationOptions()
{
PageSize = new Aspose.CAD.SizeF(image.Size.Width, image.Size.Height),
};
// save resultant PDF
image.Save("****" + "***", new Aspose.CAD.ImageOptions.PdfOptions() { VectorRasterizationOptions = rasterizationOptions });
}
The pdf that i've got this:
another image
I want the building to be in the center of the pdf file and big enough to be useful for the user. How could i fix this view and make it clear?
I have observed the sample code shared by you. Can you please share that what issue you are having in exported PDF. Can you please share the source DWG file along with expected output PDF. Also, in your above image, the watermark on top left corner will be removed when you will set license of Aspose.CAD in your application.
I am working as Support developer/ Evangelist at Aspose.
Many Thanks
I suggest you to please try using following sample code on your end to set the print area for rendering file.
var cadImage =(CadImage) Aspose.CAD.Image.Load("filePath");
CadRasterizationOptions rasterizationOptions = new CadRasterizationOptions();
rasterizationOptions.Layouts = new string[] { "Model" };
rasterizationOptions.NoScaling = true;
// note: preserving some empty borders around part of image is the responsibility of customer
// top left point of region to draw
Point topLeft = new Point(6156, 7053);
double width = 3108;
double height = 2489;
CadVportTableObject newView = new CadVportTableObject();
newView.Name = new CadStringParameter();
newView.Name.Init("*Active");
newView.CenterPoint.X = topLeft.X + width / 2f;
newView.CenterPoint.Y = topLeft.Y - height / 2f;
newView.ViewHeight.Value = height;
newView.ViewAspectRatio.Value = width / height;
for (int i = 0; i < cadImage.ViewPorts.Count; i++)
{
CadVportTableObject currentView = (CadVportTableObject)(cadImage.ViewPorts[i]);
if (cadImage.ViewPorts.Count == 1 || string.Equals(currentView.Name.Value.ToLowerInvariant(), "*active"))
{
cadImage.ViewPorts[i] = newView;
break;
}
}
cadImage.Save("Saved.pdf", new Aspose.CAD.ImageOptions.PdfOptions() { VectorRasterizationOptions = rasterizationOptions });

ABCPDF Converting Text PDF to Image PDF with correct layout

I am trying to convert a text pdf to image pdf, and for that I found the following article:
ABCpdf convert text to image
So I took the code an produced the following code:
WebSupergoo.ABCpdf9.Doc firstDoc = new WebSupergoo.ABCpdf9.Doc();
WebSupergoo.ABCpdf9.Doc secondDoc = new WebSupergoo.ABCpdf9.Doc();
firstDoc.Read(#"C:\pdf1.pdf");
for (int i = 1; i <= firstDoc.PageCount; i++)
{
secondDoc.Page = secondDoc.AddPage();
firstDoc.PageNumber = i;
secondDoc.MediaBox.String = firstDoc.MediaBox.String;
using (Bitmap bm = firstDoc.Rendering.GetBitmap())
{
secondDoc.AddImageBitmap(bm, false);
}
}
secondDoc.Save(#"c:\pdf2.pdf");
Now the code above works well except when I have pdf documents that have some page in portrait layout and other pages in landscape. What ends happening is the following:
let's say that I have a pdf document that has;
Page 1 - portrait
Page 2 - landscape
Page 3 - portrait
Page 4 - portrait
The result that this code is producing is:
Page 1 - portrait
Page 2 - portrait
Page 3 - landscape
Page 4 - portrait
Is there anything else that I would need to do other than setting the MediaBox to have the correct outcome?
Thanks for the helpful feedback in the comments, I was able to solve the problem by putting
secondDoc.Page = secondDoc.AddPage();
after
secondDoc.MediaBox.String = firstDoc.MediaBox.String;
The working code now looks like this:
WebSupergoo.ABCpdf9.Doc firstDoc = new WebSupergoo.ABCpdf9.Doc();
WebSupergoo.ABCpdf9.Doc secondDoc = new WebSupergoo.ABCpdf9.Doc();
firstDoc.Read(#"C:\pdf1.pdf");
for (int i = 1; i <= firstDoc.PageCount; i++)
{
firstDoc.PageNumber = i;
secondDoc.MediaBox.String = firstDoc.MediaBox.String;
secondDoc.Page = secondDoc.AddPage();
using (Bitmap bm = firstDoc.Rendering.GetBitmap())
{
secondDoc.AddImageBitmap(bm, false);
}
}
secondDoc.Save(#"c:\pdf2.pdf");

Change the inset of a specific page with abcpdf

I use abcpdf to create a pdf from a html string. The following snippet shows the way I do it:
var pdfDocument = new Doc();
pdfDocument.Page = pdfDocument.AddPage();
pdfDocument.Font = pdfDocument.AddFont("Times-Roman");
pdfDocument.FontSize = 12;
var documentId = pdfDocument.AddImageHtml(innerHtml);
var counter = 0;
while (true)
{
counter++;
if (!pdfDocument.Chainable(documentId))
{
break;
}
pdfDocument.Page = pdfDocument.AddPage();
// how to add a inset of 20, 0 on every page after the second? The following 2lines don't affect the pdf pages
if (counter >= 3)
pdfDocument.Rect.Inset(20, 0);
documentId = pdfDocument.AddImageToChain(documentId);
}
After the AddPage I want to add a new inset for every page with pagenumber > 2
Thanks in advance
I can assure you that your inset call will be having an effect. Try calling FrameRect on each page and you shuld be able to see this.
So why is it that you are not seeing the effect you are expecting?
Well your HTML has a fixed width at the point you call AddImageUrl/HTML. Each subsequent call to AddImageToChain utilizes this fixed width.
If in your 'inset' pages you reduce the height of the area on the page you will get the next chunk of the page truncated to that height.
If in your 'inset' pages you reduce the width of the area then things become more difficult. The width is fixed so it can't be changed. Instead ABCpdf will scale the page down so that it does fit.
So if you reduce the width from say 600 points to 580 points then the scale factor for this content would be 580/600 = 97%.
Most likely this is what is happening but because the scale factor is small you are not noticing it.
I work on ABCpdf and my replies may contain concepts based around ABCpdf. It's what I know. :-)
Comment #1 from SwissCoder was right. AddImageHtml already adds the first page. After also contacting the WebSuperGoo support, they recommend me to use PageCountof class Doc.
while (true)
{
if (!pdfDocument.Chainable(documentId))
{
break;
}
pdfDocument.Page = pdfDocument.AddPage();
if (pdfDocument.PageCount >= 3)
pdfDocument.Rect.Inset(0, 20);
documentId = pdfDocument.AddImageToChain(documentId);
}
The other solution would be to adjust the index to count unto required pagenumber - 1 as ÀddImageHtml already adds the first page to the document.

Categories