Get the number of rows that a cell Itextsharp occupies
all.
I want to know if there is a method to get the exact rows occupied by a specific cell.
I am currently doing this using ff. Function:
private int GetRowLines(string content, float maxFloatPerRow)
{
if (string.IsNullOrEmpty(content))
content = string.Empty;
float noteFwidth = BaseFont.GetWidthPoint(content, cellFont.Size);
int nextRowLines = 0;
var test = noteFwidth / maxFloatPerRow;
nextRowLines = (int)Math.Ceiling(test);
return nextRowLines == 0 ? 1 : nextRowLines;
}
The only problem is that I need to provide maxFloatPerRow
which is only trial and error.
- I will have a pdf with a lot
"i"
in a specific cell that I want to test.- Then I will copy the entire contents of that cell for 1 row (these will be the maximum characters in one row for this cell).
- Get the float width of this maximum amount for each row using the method
BaseFont.GetWidthPoint
.
However, I want to create a utility method that will give me the number of lines the content will occupy, given the Fwidth of the title, font of the content, and the content itself. More if needed.
EDIT based on a comment:
I am using itext v.3.1.7.0
and I am creating pdf without editing the existing one.
I hope you guys have something to share. Thank.
source to share
After a few days of experimenting, here's the workaround I've come up with so far and it seems accurate enough:
/// <summary>
/// Gets number of rows this cell occupies.
/// </summary>
/// <param name="headerFwidths">The fwidths of the headers of the table this cell belongs to</param>
/// <param name="index">The column index of the cell to check</param>
/// <param name="cCell">The cell to check</param>
/// <returns>int the number of rows</returns>
public int GetRowLines(float[] headerFwidths, int index, CellValue cCell) {
float tableWidth = Document.GetRight(Document.LeftMargin);
float lPad = cCell.PaddingLeft != null ? cCell.PaddingLeft.Value : 2f;
float rPad = cCell.PaddingRight != null ? cCell.PaddingRight.Value : 2f;
float maxFloatPerRow = ((tableWidth / headerFwidths.Sum()) * headerFwidths[index]) - (lPad + rPad);
string content = string.IsNullOrEmpty(cCell.Title) ? string.Empty : cCell.Title;
int rowLines = 0;
float cellFontWidth = BaseFont.GetWidthPoint(content, cCell.CellFont.Size);
rowLines = (int)Math.Ceiling(cellFontWidth / maxFloatPerRow);
return rowLines == 0 ? 1 : rowLines;
}
So how does it work:
You get float[] fWidths
the table headers first , because the cells mostly follow the header fwidth
.
Then you get the width of the document with Document.GetRight(Document.LeftMargin)
.
The next step is to get a fill check for CellValue
.
Note : CellValue
- our custom class which is derived from the PdfPCell
iTextSharp class .
So, using the table width, cell padding and header files, we can estimate maxFloatPerRow
:
float maxFloatPerRow = ((tableWidth / headerFwidths.Sum()) * headerFwidths[index]) - (lPad + rPad);
We can get the float value for a cell cellFontWidth
using BaseFont.GetWidthPoint
.
Finally, we'll divide ours cellFontWidth
by ours maxFloatPerRow
to get the number of rows the cell occupies.
This may not be 100% accurate, but for now it works for our case.
I hope this helps anyone who has the same case as me. (I accept this as an answer, but in case you have a better answer please feel free to post. I will gladly acknowledge your answer if it turns out to be better.)
source to share
There are several options. I will only describe the high level points of the two simplest solutions
Approach 1
Use pdf2Data (this is iText7 add-on), it can turn PDF documents into XML data (given a template that matches the document). This add-on is only available for iText7, so it will require some relocation.
Approach 2
- use an EventListener to collect all line drawing events from the landing page.
- after you have all the line rendering information, copy it by pasting the lines into the same cluster if and only if they intersect at a 90 degree angle
- check each cluster, a cluster that contains a certain threshold of rows can be considered a table
- Make a vertical projection of all horizontal lines, this tells you how many rows (in total, in the whole table)
- do a horizontal projection of all vertical lines, this tells you how many columns there are (total, in the whole table).
- Now that you have the boundaries of each cell, you can repeat steps 4 and 5 for each sub-range of coordinates within the table to determine exactly how many rows / columns are within that range of coordinates.
source to share