I'm trying to fill the remaining space of the last line of a paragraph using iText7 with C#:
var par = new Paragraph(text);
par.Add(c);
document.Add(par);
How can i add - char to fill the space left by the line? Something like LineSeparator(new DashedLine() but from the beginning on the last character of my paragraph instead of new line.
You can use the concept of tabs and tab stops for it. This concept is not iText-specific.
Roughly speaking you can define points (tab stops) and adding a tab would "jump" to the next point. In your case the tab stop is the end of the line and you only need one tab.
Here is a complete example that uses small dashes on the baseline as the filling. You can implement ILineDrawer yourself to customize the behavior or subclass/configure an existing implementation. The code is in Java, but to convert it to C# you basically need to do some capitalization and that's it.
Document doc = ....;
Paragraph p = new Paragraph("Hello world").add(new Tab());
ILineDrawer filling = new DashedLine();
PageSize pageSize = doc.getPdfDocument().getDefaultPageSize();
Rectangle effectivePageSize = doc.getPageEffectiveArea(pageSize);
float rightTabStopPoint = effectivePageSize.getWidth();
TabStop tabStop = new TabStop(rightTabStopPoint, TabAlignment.LEFT, filling);
p.addTabStops(tabStop);
doc.add(p);
Result looks as follows:
Related
I try to write a pdf file with a header, logo and table using iText7 in c#.
I never used iText7 before and therefore I don't know how to write text in a paragraph to a fixed position.
Right now I am just using tabstops as anchors for my text. But the problem here is, when the string is too long everything following in the line will be shifted by a tabstop and the "columns" in the header aren't aligned anymore.
The following picture is what I want too achieve:
This picture shows what happens if a string gets too long (in this example I used a long username):
Here is a code snippet I use to write one line of the header:
// generate 8 tabstops to split pdf in equal sections
List<TabStop> tabStops = new List<TabStop>();
for (uint i = 0; i < 8; i++)
{
float tabSize = pageSize.GetWidth() / 8;
tabStops.Add(new TabStop(tabSize, TabAlignment.LEFT));
}
Paragraph p = new Paragraph();
p.SetFontSize(10);
// add tabstops to paragraph for text alignment
p.AddTabStops(tabStops);
// add title of header
p.Add(title1).Add("\n");
// write line one of header
p.Add("Serie: ").Add(new Tab()).Add(info.serial.ToString())
.Add(new Tab()).Add(new Tab())
.Add("Input CSV: ").Add(new Tab()).Add(info.inputFileName)
.Add(new Tab()).Add(new Tab()).Add("Out-Series: ")
.Add(info.serial.ToString()).Add("\n");
// line 2...
p.Add("User: ").Add(new Tab()).Add(info.username)
.Add(new Tab()).Add(new Tab()).Add(new Tab())
.Add("qPCR-Datei: ").Add(new Tab()).Add(info.qpcr1FileName)
.Add(new Tab()).Add(new Tab()).Add(new Tab())
.Add("STR-Out: ").Add(strFileName).Add("\n");
I hope someone can help me show me a better way of text alignment or has information where to look at.
Another nice tip would be how I can keep linebreaks in the same tab stop section. for example if a file name gets too long (s. "STR-Out: " in picture) the linebreak will be executed but the part of the filename in the new line should stay at the tab stop behind "STR-OUT: "
Instead of Tab/Tabspace use Tables and Cells so that alignment will be proper.
Create table of column 8 size (Label, Value, space , Label, Value, Space, Label, Value)
Use this sample Code.
PdfPTable table = new PdfPTable(8);
PdfPCell cell;
cell = new PdfPCell();
cell.setRowspan(2); //only if spanning needed
table.addCell(cell);
for(int aw=0;aw<8;aw++){
table.addCell("hi");
}
Thanks #shihabudheenk for pointing me in the right direction with the idea of using a table.
Just had to adjust some code to iText7.
First thing is that
Table headerTable = new Table().SetBorder(Border.NO_BORDER);
has no effect in iText7, you have to set the option for each cell individually like:
Cell cell = new Cell().SetBorder(Border.NO_BORDER);
but here is the problem that
cell.Add()
in iText7 only accepts IBlockElement as parameter so i have too use it like this:
cell.Add(new Paragraph("text");
which is pretty annoying doing that for every cell over and over again. Therefore i used a removeBorder function as suggested here
So the final code I use to build the header looks like this:
// initialize table with fixed column sizes
Table headerTable = new Table(UnitValue.CreatePercentArray(
new[] { 1f, 1.2f, 1f, 1.8f, 0.7f, 2.5f })).SetFixedLayout();
// write headerline 1
headerTable.AddCell("Serie: ").AddCell(info.serial.ToString())
.AddCell("Input CSV: ")
.AddCell(info.inputFileName)
// write remaining lines...
....
// remove boarder from all cells
removeBorder(headerTable);
private static void removeBorder(Table table)
{
foreach (IElement iElement in table.GetChildren())
{
((Cell)iElement).SetBorder(Border.NO_BORDER);
}
}
i'm trying to create a pdf looks like this
but when i try string padding, it looks like this in pdf file
here is the part of the c# code i tried. myExcelData is filled from excel file.
for (int i = 0; i < 15; i++)
{
Chunk cSira = new Chunk((i + 1).ToString().PadRight(10), icerikFont);
Chunk cHizmet = new Chunk(myExcelData.Tables[0].Rows[i][6].ToString().PadRight(80), icerikFont);
Chunk cAdet = new Chunk(myExcelData.Tables[0].Rows[i][1].ToString().PadRight(10), icerikFont);
Chunk cBirimFiyat = new Chunk(myExcelData.Tables[0].Rows[i][2].ToString().PadRight(20), icerikFont);
Chunk cTutar = new Chunk(myExcelData.Tables[0].Rows[i][3].ToString().PadRight(20), icerikFont);
d.Add(cSira);
d.Add(cHizmet);
d.Add(cAdet);
d.Add(cBirimFiyat);
d.Add(cTutar);
d.Add(Chunk.NEWLINE);
}
There are two ways to do this:
use a monospaced font (e.g. Courier). Currently you're using a font of which the width of the different characters is different.
download chapter 2 of my book and learn how to use TAB CHUNKS (look for that title on page 48).
Use a PdfPTable as mkl indicates in his comment (maybe you were overlooking the obvious)
If you need a code snippet for option 2, take a look at the DirectorOverview3 example. The result looks like this. If you don't understand Java, read the C# example.
I am trying to access the indentation levels of various bulleted list items. So I created a simple function:
private float[] findIndentSpacing(TextRange t, int level) {
if(level == 1) {
RulerLevel rl = t.Parent.Ruler.Levels(2);
//bullet must start at 0 on the first level for now
return new float[2] { 0, rl.LeftMargin * Settings.Scaler() };
} else {
RulerLevel rl = t.Parent.Ruler.Levels[level];
return new float[2] { rl.FirstMargin * Settings.Scaler(), rl.LeftMargin * Settings.Scaler() };
}
}
So that first if statement is a work around. The first level LeftMargin always returns: -2.14748365E+9 for some reason. I've tried to just grab levels after the first and they return actual values. That being said, after one level has been accessed all other levels change and become equal. For example if I try to access: t.Parent.Ruler.Levels[2].FirstMargin, then for some reason t.Parent.Ruler.Levels[3].FirstMargin become the same, and so forth. LeftMargin changes also.
I've tried accessing the ruler object in different ways: by selection, by shape, by text and every way I've thought to try the result is the same.
Ideas?
More info:
I read the following threads, but they are more about writing than reading, but I feel like the problem is similar: PowerPoint Programming: Indentation with Ruler margin levels not working?
http://answers.microsoft.com/en-us/office/forum/office_2007-customize/why-shapetextframerulerlevelsi-cant-set-the-bullet/9eac3e46-b13b-433e-b588-216ead1d9c1a?tab=AllReplies#tabs
I made this one: http://answers.microsoft.com/en-us/office/forum/office_2010-customize/find-bullet-spacing-information-in-an-automated/4525b6b8-6331-4f33-8127-789ea3641589?page=1&tm=1336535132591
In 2007 and 2010 I think you'll need to work with TextRange2 and TextFrame2 objects.
In PPT 2003 and previous, the TextFrame could have 5 indent levels, and all paragraphs at a given indent level shared the same LeftMargin and FirstMargin.
From 2007 on, TextFrames can have up to 9 indent levels, and each paragraph can have its own Left/First margins, independent of the margins set on other paragraphs at the same indent level.
Try this in PPT's VBA IDE. Select the text you're looking at then:
Sub Levels()
Dim oSh as Shape
Dim x As Long
Set oSh = ActiveWindow.Selection.ShapeRange(1)
With oSh.TextFrame2.Ruler
For x = 1 to .Count
Debug.Print .Levels(x).FirstMargin
Debug.Print .Levels(x).LeftMargin
Next
End With
End Sub
Is it possible to bold a single word within a sentence with iTextSharp? I am trying to bold several individual words without having to break the string into individual phrases.
I want to this type of out put
Eg:REASON(S) FOR CANCELLATION: See Statutory reason(s) designated by Code No(s) 1 on the reverse side hereof.
My actual output is below
Eg:REASON(S) FOR CANCELLATION: See Statutory reason(s) designated by Code No(s) 1 on the reverse side hereof.
Code
pdftb4 = new PdfPTable(1);
pdftb4.WidthPercentage = 100;
width = new float[1];
width[0] = 0.7F;
pdftb4.SetWidths(width);
pdfcel4 = new PdfPCell(new Phrase("\n REASON(S) FOR CANCELLATION: See Statutoryreason(s) designated by Code No(s) 1 on the reverse side hereof", docBlackFont10));
pdfcel4.Border = 0;
pdfcel4.HorizontalAlignment = Element.ALIGN_LEFT;
pdftb4.AddCell(pdfcel4);
objDocument.Add(pdftb4);
somebody please help me
The way to accomplish what you are trying is with Chunks. A simple example is:
var normalFont = FontFactory.GetFont(FontFactory.HELVETICA, 12);
var boldFont = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 12);
var phrase = new Phrase();
phrase.Add(new Chunk("REASON(S) FOR CANCELLATION:", boldFont));
phrase.Add(new Chunk(" See Statutoryreason(s) designated by Code No(s) 1 on the reverse side hereof", normalFont));
Can also create font like
Font verdanaBold = FontFactory.GetFont("Verdana", 7f, Font.BOLD);
Maybe this link Bolding with Rich Text Values in iTextSharp will help?
Not sure if it fits your scenario completely but might get you where you need to go.
Only in the System.Console do I get the result, it print the number of characters that are left, and it update it
So whats wrong, how do i update it in the Element?
Hope you guys can help me with this.
Console:
Characters typed(left): in Value it should write the number of characters that are left.
var root = new RootElement ("Send Message");
var messageElement = new MultilineEntryElement ("", "0123456789")
{
Editable = true,
Height = 120
};
var messageSection = new Section ();
int leangtOfChar = 200 - messageElement.Value.Length;
var lengthElement = new StringElement ("characters typed:", leangtOfChar.ToString());
messageElement.Changed += delegate {
System.Console.WriteLine (leangtOfChar.ToString ());
//lengthElement.Value = (leangtOfChar.ToString());
};
root.Add(messageSection);
The problem is that when you update a normal StringElement it doesn't automatically update the attached cell.
To force an update for just that cell, I would recommend either:
calling root.Reload(lengthElement, UITableViewRowAnimation.Fade) after you change the value
or using a custom element/cell type instead of StringElement - basically you could model this on the simple code in BooleanElement - but use a UILabel as the accessory instead of a UISwitch.
If you wanted to go further - to actually allow StringElement to be updated without a reload - then you can do this by modifying the Element class to track whether a cell instance is currently attached. I've done exactly that in a databinding branch of monotouch.dialog - https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Dialog/Dialog/Elements/Element.cs - but this is almost certainly overkill for what you are trying to do right now.