How can itext7 remove the space between paragraph text and paragraph top? - .net-core

Using itext7, I created a pdf with two paragraphs.
string cardPdf = "card.pdf"; float cardWidth = 266.5f; float cardHeight = 164.4f;
using (PdfDocument cardDoc = new PdfDocument(new PdfWriter(cardPdf)))
using (Document doc = new Document(cardDoc))
{
PdfPage page = cardDoc.AddNewPage(new iText.Kernel.Geom.PageSize(cardWidth, cardHeight));
Paragraph pg1 = new Paragraph("WriteParagraph 1").SetFontSize(10f);
pg1.SetBackgroundColor(iText.Kernel.Colors.ColorConstants.YELLOW);
doc.Add(pg1);
Paragraph pg2 = new Paragraph("WriteParagraph 2").SetFontSize(20f);
pg2.SetBackgroundColor(iText.Kernel.Colors.ColorConstants.YELLOW);
doc.Add(pg2);
}
I found that there are gaps at the top of the paragraph text and the background rectangle, and different font sizes cause different gaps. How can I remove the spacing.

You can use either of those methods to reduce space around to document.
Document Level
SetMargins(float topMargin, float rightMargin, float bottomMargin, float leftMargin);
SetTopMargin(float topMargin);
SetRightMargin(float rightMargin);
SetBottomMargin(float bottomMargin);
SetLeftMargin(float leftMargin);
Paragraph Level
SetMargins(float topMargin, float rightMargin, float bottomMargin, float leftMargin);
SetMarginTop(float topMargin);
SetMarginRight(float rightMargin);
SetMarginBottom(float bottomMargin);
SetMarginLeft(float leftMargin);
To control line spacing/leading for the paragraph.
SetMultipliedLeading(float leadingValue);
If need to control leading on overall document level.
SetProperty(int property, object value);
SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, float leading Value);
Try this:
string cardPdf = "card.pdf"; float cardWidth = 266.5f; float cardHeight = 164.4f;
using (PdfDocument cardDoc = new PdfDocument(new PdfWriter(cardPdf)))
using (Document doc = new Document(cardDoc))
{
doc.SetMargins(15f, 20f, 15f, 20f);
PdfPage page = cardDoc.AddNewPage(new iText.Kernel.Geom.PageSize(cardWidth, cardHeight));
Paragraph pg1 = new Paragraph("WriteParagraph 1").SetFontSize(10f);
pg1.SetBackgroundColor(iText.Kernel.Colors.ColorConstants.YELLOW);
pg1.SetMultipliedLeading(0.8f);
doc.Add(pg1);
Paragraph pg2 = new Paragraph("WriteParagraph 2").SetFontSize(20f);
pg2.SetMultipliedLeading(0.8f);
pg2.SetMarginTop(0f);
pg2.SetBackgroundColor(iText.Kernel.Colors.ColorConstants.YELLOW);
doc.Add(pg2);
}

Related

PDFsharp - Change page size and scale content

Is it possible to scale a page from e.g. A2 to A1 with PDFsharp?
I can set the size of the page via Size, Width and Height. But how can I scale the content of the page?
based on the comment from Vive and the link provided there, here an example for resizing to A4 with C#:
you must include:
using PdfSharp.Pdf;
using PdfSharp.Drawing;
using PdfSharp;
then:
// resize this file from A3 to A4
string filename = #"C:\temp\A3.pdf";
// Create the new output document (A4)
PdfDocument outputDocument = new PdfDocument();
outputDocument.PageLayout = PdfPageLayout.SinglePage;
XGraphics gfx;
XRect box;
// Open the file to resize
XPdfForm form = XPdfForm.FromFile(filename);
// Add a new page to the output document
PdfPage page = outputDocument.AddPage();
if (form.PixelWidth > form.PixelHeight)
page.Orientation = PageOrientation.Landscape;
else
page.Orientation = PageOrientation.Portrait;
double width = page.Width;
double height = page.Height;
gfx = XGraphics.FromPdfPage(page);
box = new XRect(0, 0, width, height);
gfx.DrawImage(form, box);
// Save the document...
string newfilename = #"c:\temp\resized.pdf";
outputDocument.Save(newfilename);
You can use DrawImage() to draw an existing PDF page on a new PDF page. You can specify the destination rectangle and thus you can scale the page as needed.
Use the XPdfForm class to access the existing PDF file.
See the Two Pages on One sample for details:
http://www.pdfsharp.net/wiki/TwoPagesOnOne-sample.ashx

How do you insert HTML into a text node in AngleSharp?

I'm parsing a document with AngleSharp. I have a text node (NodeName: "#text") and I want to insert some HTML in it. I can certainly reset NodeValue to whatever I want, but it's still a text node, so all the brackets are escaped.
How do I take the string value of a text node, inject some HTML into it, then have a parsed DOM representation that that HTML take the place of the original text node?
I guess what you want is to replace a single text node by multiple nodes.
For instance <div>foo</div>, i.e.,
+ root
+ textnode
becomes
+ root
+ textnode (1)
+ element
+ textnode (2)
which could <div>f<b>o</b>o</div>. The simplest way I can think of is just replacing the node.
var source = #"<div>foo</div>";
var parser = new HtmlParser();
var document = parser.Parse(source);
var div = document.QuerySelector("div");
div.InnerHtml = div.InnerHtml.Replace("foo", "f<b>o</b>o");
Now you can argue that just replacing the text may not be what you want. You maybe have already elements that you want to insert. Therefore a better (yet more complex) way would be to split the text node and insert the remaining contents.
var source = #"<div>foo</div>";
var parser = new HtmlParser();
var document = parser.Parse(source);
var div = document.QuerySelector("div");
var text = div.TextContent;
div.RemoveChild(div.FirstChild); // assuming there is only one child
var bold = document.CreateElement("b");
bold.TextContent = text.Substring(1, 1); //o
div.Append(
document.CreateTextNode(text.Substring(0, 1)), //f
bold,
document.CreateTextNode(text.Substring(2, 1)));//o
Depending in your use-case there may be a more simple solution.

MigraDoc - only Last Page Footer

I have this code:
Document document = new Document();
Section sec = document.AddSection();
Paragraph par;
for (int i = 0; i < 50; i++)
{
par = sec.AddParagraph();
par.AddText("Wiki je označení webů (nebo obecněji hypertextových dokumentů), které umožňují uživatelům přidávat obsah podobně jako v internetových diskusích, ale navíc jim také umožňují měnit stávající obsah; v přeneseném smyslu se jako wiki označuje software, který takovéto weby vytváří.Původně se termín wiki používal zcela opačně. Wiki bylo označení typu softwaru a weby postavené.");
}
par = sec.Headers.Primary.AddParagraph();
par.AddText("hlavicka");
Borders hranice = new Borders();
hranice.Width = 1;
sec.Headers.Primary.Format.Borders = hranice;
sec.AddImage("images.jpg");
par = sec.AddParagraph();
par.AddText("paticka");
PdfDocumentRenderer print = new PdfDocumentRenderer(false, PdfFontEmbedding.Always);
print.Document = document;
print.RenderDocument();
print.PdfDocument.Save("ahoj.pdf");
I need to make a Footer only on the last page. Is it possible?
MemoryStream PdfDocumnet()
{
Document pdfdoc = new MigraDoc.DocumentObjectModel.Document();
pdfdoc.Info.Title = "Doc Title";
pdfdoc.Info.Subject = "Doc Subject";
DefineProformaStyles(pdfdoc);
CreatePdf(pdfdoc);
MemoryStream stream = new MemoryStream();
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true, PdfSharp.Pdf.PdfFontEmbedding.Always);
renderer.Document = pdfdoc;
renderer.RenderDocument();
renderer.Save(stream, false);
return stream;
}
private void CreatePdf(Document pdfDoc)
{
pdfDoc.DefaultPageSetup.HeaderDistance = "0.8cm";
pdfDoc.DefaultPageSetup.FooterDistance = "0.6cm";
MigraDoc.DocumentObjectModel.Section section = pdfDoc.AddSection();
section.PageSetup.TopMargin = "6.8cm"; //Unit.FromCentimeter(3.0);
section.PageSetup.BottomMargin = "3.4cm"; //Unit.FromCentimeter(3.0);
// HEADER ///////////////////////////////////////////////////////////////////////////////////
MigraDoc.DocumentObjectModel.Tables.Table tableh1 = section.Headers.Primary.AddTable();
Column colh1 = tableh1.AddColumn("10.8cm");
Column colh2 = tableh1.AddColumn("8cm");
colh2.Format.Alignment = ParagraphAlignment.Right;
// ...
// ... add content to header
// ...
//FOOTER for every page //////////////////////////////////////////////////////////////////////
MigraDoc.DocumentObjectModel.Tables.Table tablef2 = section.Footers.Primary.AddTable();
tablef2.Style = "Table";
//add content to footer
// BODY ///////////////////////////////////////////////////////////////////////////////////
MigraDoc.DocumentObjectModel.Tables.Table tableC = section.AddTable();
TextFrame frm0 = section.AddTextFrame();
Paragraph prg1 = section.AddParagraph();
//....
//.....
//FOOTER FOR ONLY LAST PAGE //////////////////////////////////////////////////////////////////
//Add an empty paragraph. If there is not enough space to fit in current page then ... page break
Paragraph emptyPar = section.AddParagraph();
emptyPar.Format.SpaceBefore = "2.6cm";
//add the special footer
string lastPageFooterImgFile = HttpContext.Current.Server.MapPath("/company/CompanyFooter.png");
TextFrame lastframe = section.AddTextFrame();
lastframe.Height = "2.6cm";
lastframe.RelativeVertical = RelativeVertical.Page;
lastframe.Top = "24cm"; // 24cm + 2.6cm + footer_for_every_page.Height = Page.Height
lastframe.AddImage(lastPageFooterImgFile);
}
private void DefineProformaStyles(Document Doc)
{
Doc.DefaultPageSetup.LeftMargin = "1.3cm";
MigraDoc.DocumentObjectModel.Style style = Doc.Styles["Normal"];
style = Doc.Styles[StyleNames.Header];
style.ParagraphFormat.AddTabStop("1cm", TabAlignment.Right);
style = Doc.Styles[StyleNames.Footer];
style.ParagraphFormat.AddTabStop("1cm", TabAlignment.Center);
style = Doc.Styles.AddStyle("Table", "Normal");
style.Font.Name = "Times New Roman";
style.Font.Size = 9;
style = Doc.Styles.AddStyle("Reference", "Normal");
style.ParagraphFormat.SpaceBefore = "1mm";
style.ParagraphFormat.SpaceAfter = "1mm";
style.ParagraphFormat.TabStops.AddTabStop("1cm", TabAlignment.Right);
}
There is no way to create a real footer on the last page.
You can create a TextFrame with your last paragraph. TextFrames are Shapes and can be placed at an absolute position on the page, so you can also place them where the Footer would be.
For example:
You need a 30mm place over the footer on the last page. (That could be a signature field.)
Define the PageSetup without this place (only footer hight + your distance from the bottom of the page)
Define your 30mm paragraph or table as TextFrame on a fix position: TextFrame.RelativeVertical = RelativeVertical.Page; frame.Top = ShapePosition.Bottom;
Define an empty paragraph as the last paragraph of the document with paragraph.Format.SpaceBefore = 30mm
Now the 30mm empty paragraph is on the end of all Documents and the signature overlapped it or the place for signature is not enough. Then the 30mm empty place forces a page break.

Can PDFsharp automatically split a string over multiple pages?

I want to add the ability to generate a PDF of the content in my application (for simplicity, it will be text-only).
Is there any way to automatically work out how much content will fit in a single page, or to get any content that spills over one page to create a second (third, fourth, etc) page?
I can easily work it out for blocks of text - just split the text by a number of characters into a string array and then print each page in turn - but when the text has a lot of white space and character returns, this doesn't work.
Any advice?
Current code:
public void Generate(string title, string content, string filename)
{
PdfDocument document = new PdfDocument();
PdfPage page;
document.Info.Title = title;
XFont font = new XFont("Verdana", 10, XFontStyle.Regular);
List<String> splitText = new List<string>();
string textCopy = content;
int ptr = 0;
int maxCharacters = 3000;
while (textCopy.Length > 0)
{
//find a space in the text near the max character limit
int textLength = 0;
if (textCopy.Length > maxCharacters)
{
textLength = maxCharacters;
int spacePtr = textCopy.IndexOf(' ', textLength);
string startString = textCopy.Substring(ptr, spacePtr);
splitText.Add(startString);
int length = textCopy.Length - startString.Length;
textCopy = textCopy.Substring(spacePtr, length);
}
else
{
splitText.Add(textCopy);
textCopy = String.Empty;
}
}
foreach (string str in splitText)
{
page = document.AddPage();
// Get an XGraphics object for drawing
XGraphics gfx = XGraphics.FromPdfPage(page);
XTextFormatter tf = new XTextFormatter(gfx);
XRect rect = new XRect(40, 100, 500, 600);
gfx.DrawRectangle(XBrushes.Transparent, rect);
tf.DrawString(str, font, XBrushes.Black, rect, XStringFormats.TopLeft);
}
document.Save(filename);
}
You can download PDFsharp together with MigraDoc. MigraDoc will automatically add pages as needed, you just create a document and add your text as paragraphs.
See MigraDoc samples page:
http://pdfsharp.net/wiki/MigraDocSamples.ashx
MigraDoc is the recommended way.
If you want to stick to PDFsharp, you can use the XTextFormatter class (source included with PDFsharp) to create a new class that also supports page breaks (e.g. by returning the count of chars that fit on the current page and have the calling code create a new page and call the formatter again with the remaining text).

how to force a justified alignment on a pdfpcell

to justify a text on a pdfpcell i know these commands
PdfPCell Example= new PdfPCell(new paragraph("Some text here",MyFont));//previous created font
Example.HorizontalAlignment = Element.ALIGN_JUSTIFIED;
but i have a hmtl string , and i need to decode, and im doing like this
string txt = "long html string text"
PdfPCell Example2= new PdfPCell();
List<IElement> sr = HTMLWorker.ParseToList(new StringReader(txt ), style);//style was previous created
foreach (IElement element in sr)
{
Example2.AddElement(element);
}
Example2.SetLeading(0f, 1.5f);
Example2.Border = 0;
Example2.PaddingBottom = 20;
Table1.AddCell(Example2);//table declared previous
ok , until this point all is working and my pdfp document is fine but i need to ignore the alignment of the html string and force all text to be justified.
im tried this
Example2.HorizontalAlignment = Element.ALIGN_JUSTIFIED;
but doesnt work .
In the first example, you're working in "text mode" and the properties of the cell are respected.
As soon as you use AddElement (), you're working in "composite mode" and the properties of the cell are ignored (as documented in my book). Instead, the properties of the separate elements are used.
In answer to your question: you shouldn't define the alignment at the level of the cell, but at the level of the element.

Resources