MigraDoc - Get height of section - c#

What I'm trying to achieve is to have the same content twice on the page, separated by a dotted line, with padding so that the one copy is on the top-half and the second is on the bottom half. Something like firstSection.SpaceAfter = (height of page / 2) - (height of first section)
tl;dr: How do I calculate the height of the first section after everything is added?
I have this, which has the copied content and the dotted line, but I need the padding.
Document document = new Document();
document.Info.Title = "Testing";
Style style = document.Styles["Normal"];
style.Font = new Font("Times New Roman", 12);
Section section = document.AddSection();
section.PageSetup = document.DefaultPageSetup.Clone();
Paragraph paragraph = section.AddParagraph("Hello");
paragraph = section.AddParagraph("World");
paragraph = section.AddParagraph();
paragraph.Format.Borders.Bottom = new Border
{
Width = "1pt",
Color = Colors.Black,
Style = BorderStyle.DashLargeGap
};
paragraph = section.AddParagraph("Hello");
paragraph = section.AddParagraph("World");

To answer your question:
The content only has a height when you render it to some output format (e.g. PDF).
Let the PDF Renderer prepare the document and then you will be able to query position and height for every object in the document.
Alternative solutions:
My attempt #1 would be: create a Table and set the height of the first row to cover the top half of the page; add the contents for the lower half of the page to the second row; hide the borders to make the table invisible.
My attempt #2 would be: create a TextFrame at an absolute position for the lower half of the page; add the contents normally to the section and also add them to the TextFrame.
In both cases you must make sure the contents fit into a half page.

Related

C# Word enlarge cell using paragraphs

I would like to enlarge a cell to a certain height by using paragraphs. i have tried working with height, but it always gives me the same height back, no matter how many paragraphs i insert. is there a way to determine the exact size?
var cell = table.Cell(1, 1);
var limitHeight = 6f;
while (cell.Height <= limitHeight)
{
cell.Range.Text += "\r";
}

Autofit Row Height of Merged Cell in EPPlus

I'm using EPPlus and C# and trying to autosize/autofit the height of a row to accommodate the height needed to show all of the contents of a merged cell with text wrapping. However no matter what I try the text always truncates. Since I'm repeating this process with various text sizes on various worksheets, I don't want to hard code the row height (except to enforce a minimum height for the row). If possible I'd like to do this within EPPlus/C#.
With the cells A2:E2 merged and WrapText = true:
Cell with Text Truncated
Here's what it should look like with desired Cell Height
Here's my relevant and short C# code
Int32 intToCol;
intToCol = 5;
eppWorksheet.Cells[2, 1, 2, intToCol].Merge = true;
eppWorksheet.Cells[2, 1].Style.WrapText = true;
//Check if at the minimum height. If not, resize the row
if (eppWorksheet.Row(2).Height < 35.25)
{
eppWorksheet.Row(2).Height = 35.25;
}
I've looked at Autofit rows in EPPlus and it didn't seem to directly answer my question unless I'm reading it wrong.
Here is the solution in a reusable method. Pass in the text value, font used for the cell, summed width of the columns merged, and receive back the row height. Set the row height with the result.
Use of Method
eppWorksheet.Row(2).Height = MeasureTextHeight(cell.Value, cell.Style.Font, [enter the SUM of column widths A-E]);
Reuseable Method
public double MeasureTextHeight(string text, ExcelFont font, double width)
{
if (text.IsNullOrEmpty()) return 0.0;
var bitmap = _bitmap ?? (_bitmap = new Bitmap(1, 1));
var graphics = _graphics ?? (_graphics = Graphics.FromImage(bitmap));
var pixelWidth = Convert.ToInt32(width * 7); //7 pixels per excel column width
var fontSize = font.Size * 1.01f;
var drawingFont = new Font(font.Name, fontSize);
var size = graphics.MeasureString(text, drawingFont, pixelWidth, new StringFormat { FormatFlags = StringFormatFlags.MeasureTrailingSpaces });
//72 DPI and 96 points per inch. Excel height in points with max of 409 per Excel requirements.
return Math.Min(Convert.ToDouble(size.Height) * 72 / 96, 409);
}
I have used a workaround for this and I a had print area A:Q.
I copied merged cells value to column z.
set width of column z to merge cells width.
Then set auto row height true in format.
Hide the z column.
Set print area A:Q
Cons:
There are duplicate data. But we are okay since report is printing and not print z column.
Pros:
Row height works correctly not like calculation method.
Had to tweak the code a little bit by removing the multiplication factor at the return line. May be because i am using this code to get the width of the column.
ws1.Column(colIndx).Width * 7
The multiplication factor is the number of columns been merged.

How to insert the total pages number in the footer of each page of an iTextSharp document? [duplicate]

This question already has answers here:
Page X of Y issue
(2 answers)
Closed 8 years ago.
I have the following situation to handle using iTextSharp: I am creating a PDF report and I don't know previously the number of the pages.
In the footer of each page I insert the page number as: "1/x" where x is the total pages number of my report.
At this time I have a class named PdfHeaderFooter that extends PdfPageEventHelper in which I implement the OnEndPage() to create the footer into my PDF.
// write on end of each page
public override void OnEndPage(PdfWriter writer, Document document)
{
base.OnEndPage(writer, document);
PdfPTable tabFoot = new PdfPTable(new float[] { 1F });
tabFoot.TotalWidth = document.Right - document.Left;
tabFoot.DefaultCell.Border = PdfPCell.NO_BORDER;
tabFoot.DefaultCell.CellEvent = new RoundedBorder();
PdfPTable innerTable = new PdfPTable(2);
innerTable.SetWidths(new int[] { 247, 246 });
innerTable.TotalWidth = document.Right - document.Left;
innerTable.DefaultCell.Border = PdfPCell.NO_BORDER;
PdfPCell innerCellLeft = new PdfPCell(new Phrase("Early Warning - Bollettino")) { Border = PdfPCell.NO_BORDER, Padding = 5, MinimumHeight = 20, HorizontalAlignment = Element.ALIGN_LEFT };
PdfPCell innerCellRight = new PdfPCell(new Phrase("Pag. " + numPagina + "/5")) { Border = PdfPCell.NO_BORDER, Padding = 5, MinimumHeight = 20, HorizontalAlignment = Element.ALIGN_RIGHT };
innerTable.AddCell(innerCellLeft);
innerTable.AddCell(innerCellRight);
tabFoot.AddCell(innerTable);
tabFoot.WriteSelectedRows(0, -1, document.Left, document.Bottom, writer.DirectContent);
numPagina++;
}
As you can see at this time I handle the situation using:
PdfPCell innerCellRight = new PdfPCell(new Phrase("Pag. " + numPagina + "/5"))
But in this way the total page number is fiexed (/5) but I can't previously know it the pages are 5 or a different number.
So I am thinking that I can handle the situation in the following way:
1) I can count the NewPage() call in the class that generate
2) Then I can try to modify the value of the total page int the footer of each page
But I don't know if this is a smart solution or if it is possibile to do
At the moment you're adding the page numbers (e.g. page X of Y), you know the value of X, but there's no way to know the value of Y.
There are two options to solve this. You can find this in the official documentation when you look at the Page X of Y keyword page.
One option is to introduce an empty PdfTemplate where you would normally have the Y value. You can then implement the onCloseDocument() event. This event is triggered right before the document is closed. At this moment, the value of Y is known and you can draw it to the PdfTemplate.
The other option is to create the PDF in two passes. You first create it in memory without "Page X of Y". Then you use PdfStamper to add the correct Page X of Y values (because you know the total number of pages from the first pass).
P.S. if you need code samples, you can find the C# ports of the Java examples here.

Issue with set up paragraph width in MigraDoc

How to set up paragraph width in MigraDoc? All what I imagine is create table and set the column width and then paragraph populate all width. But I need something like next:
var paragraph016 = section.AddParagraph();
paragraph016.Format.Borders.Bottom.Visible = true;
paragraph016.Format.WidowControl = true;
//here must be define paragraph width
Or maybe anybody know how can I draw line on the page, where I can setup width and position of my line?
I use paragraph width as a part of my 'add a horizontal rule' helper method. Using left and right indent works great:
public static void AddHorizontalRule(Section section, double percentWidth, Color? color = null)
{
double percent = (percentWidth < 0.0 || percentWidth > 1.0) ? 1.0 : percentWidth;
Color hrColor = color ?? new Color(96, 96, 96); // Lt Grey default
Unit contentWidth = section.PageSetup.PageWidth - section.PageSetup.LeftMargin - section.PageSetup.RightMargin;
Unit indentSize = (contentWidth - (percent * contentWidth)) / 2.0;
Paragraph paragraph = section.AddParagraph();
paragraph.Format.LeftIndent = indentSize;
paragraph.Format.RightIndent = indentSize;
paragraph.Format.Borders.Top.Visible = true;
paragraph.Format.Borders.Left.Visible = false;
paragraph.Format.Borders.Right.Visible = false;
paragraph.Format.Borders.Bottom.Visible = false;
paragraph.Format.Borders.Top.Color = hrColor;
}
Note that because a section's PageSetup values are 0 and therefore use the default document settings, that to use the client area width as shown above, you need to explicitly set these values in the section.PageSetup before calling this method. I do it this way so that I don't have to pass around the document nor depend on document.LastSection being the section that I am working on. I just pass in a Section object and have at it.
Enjoy!
Brian
You can set the width indirectly by specifying left and right indent. I don't know if this leads to the desired line, but it's worth a try.
A table will work.
An image would also work - best with a vector image (could be PDF), but a raster image with a single pixel in the desired color should also work.

Define different font size for text and line spacing and create an image from it using C# [duplicate]

This question already has answers here:
How to set line spacing Graphics.DrawString
(2 answers)
Closed 5 years ago.
I know how to create an image from text in C# and how to specify a certain font size for the text. But, I want to be able to have a few lines of text where the text is one font size - but the line spacing is a smaller font size - and be able to create an image from this in C#.
For example, I have three lines of text. The font size for each text line is 24 (not sure what the unit is - pixels? point?). But, I want the line spacing between each text line to only be 8.
Does anyone know how this can be accomplished?
Try to draw each line separately and define its vertical position as vertical position of the previous line plus your desired spacing.
var left = 0;
var top = 0;
var myFontSize = 12;
var mySpacing = 8;
var myFont = new Font("MyFontFamily", myFontSize);
var myBrush = Brushes.Black;
var myLines = new List<string>{
// your strings here
};
for(var i = 0; i < myLines.Count; i++)
{
var lineText = myLines[i];
// this line is needed to get line size in pixels, regardless in which units font size is specified
// also different fonts can have different image sizes for the same font size
var lineImageSize = graphics.MeasureString(lineText, myFont);
graphics.DrawString(myLines[i], myFont, myBrush, left, top + (i * (lineImageSize.Height + mySpacing)));
}

Categories

Resources