How to set paragraph line space in itextsharp ? - c#

In my C# windows Form application I use below code. it works fine. but I need to add line space for this paragraph.
var linkFont = FontFactory.GetFont(FontFactory.HELVETICA, 13, iTextSharp.text.Font.UNDERLINE, BaseColor.BLUE);
List<Anchor> anchor = new List<Anchor>();
foreach (string tName in templateName)
{
Anchor anch = new Anchor(tName, linkFont);
anch.Reference = "#" + tName;
anchor.Add(anch);
}
Paragraph templateData = new Paragraph();
templateData.Alignment = Element.ALIGN_LEFT;
for (int z = 0; z < anchor.Count; z++)
{
templateData.Add(anchor[z]);
templateData.Add(" , ");
}
output of this code is below.
Output of above code
if I use following code nothing changed.
Paragraph templateData = new Paragraph();
templateData.Alignment = Element.ALIGN_LEFT;
templateData .SetLeading(15, 1);
How can I fix this issue and add line space for this paragraph ?
Thanks

Change value of Y in:
templateData.SetLeading(15, 10); //'1' to '10' or whatever you want

Related

Break a table before a footer and make it re-start in the new page from the top

I'm creating a table with abcpdf. It should begin in the middle of the first page and break before the footer. Then it should restart at the beginning of the new page (it depends on the number of the rows).
Here is the code:
string theText = System.IO.File.ReadAllText(#"C:\Users\..file.txt")
Doc theDoc = new Doc();
theDoc.AddGrid();
theDoc.Rect.String = "10 200 600 780";
theDoc.FrameRect();
PDFTable theBigTable = new PDFTable(theDoc, 1);
theBigTable.NextRow();
theBigTable.SetRowHeight(200);
theBigTable.NextRow();
theBigTable.SetRowHeight(300);
PDFTable theTable = new PDFTable(theDoc, 5);
theTable.CellPadding = 5;
theTable.HorizontalAlignment = 1;
theText = theText.Trim();
theText = theText.Replace("\r\n", "\r");
string[] theRows = theText.Split(new char[] { '\r' });
for (int i = 0; i < theRows.Length; i++)
{
theTable.NextRow();
string[] theCols = theRows[i].Split(new char[] { '\t' });
theTable.AddHtml(theCols);
theTable.FrameColumns();
}
theTable.Frame();
theDoc.Flatten();
//footer
theDoc.Rect.String = "10 10 600 60";
theDoc.FrameRect();
theDoc.Save("output.pdf");
theDoc.Clear();
The issue is that the table re-starts in the new page in the same position (and not from the beginning) and it overrides the footer that appears only in the last page.
Any suggestions?

How can I add underlined words in a line of text in a word header object?

I need to add underlined column headers to the header objects in a document. I am using C# and Microsoft.Office.Interop.Word
The pertinent parts of the code look like this...
foreach (Word.HeaderFooter header in wordSection.Headers)
{
int[] fiscalYears = RetrieveFiscalYears(docProfile);
string paddingFY = new String(' ', 8);
Word.Paragraph colParagraph = wordRng.Paragraphs.Add();
int year;
for (int i = fiscalYears.Length - 1; i >= 0; i--)
{
year = fiscalYears[i];
colParagraph.Range.InsertAfter(MARKUP_WORD_TAB);
//begin underline
colParagraph.Range.InsertAfter(paddingFY + year.ToString() + paddingFY);
//end underline
}
colParagraph.Range.InsertAfter(MARKUP_WORD_TAB);
colParagraph = wordRng.Paragraphs.Add();
colParagraph.set_Style(wordDoc.Styles["ColumnHeadings"]);
}
Basically it needs to look similar to ...
Expended Estimated Budgeted
2015 2016 2017
--------- ---------- --------
In the body of the document, my for loop looks like
foreach (int year in fiscalYears)
{
wordApp.Selection.TypeText(MARKUP_WORD_TAB);
wordApp.Selection.Font.Underline = Word.WdUnderline.wdUnderlineSingle;
wordApp.Selection.TypeText(paddingFY + year.ToString() + paddingFY);
wordApp.Selection.Font.Underline = Word.WdUnderline.wdUnderlineNone;
}
But the when I use the selection object, it writes to the body of the document, not to the header/footer objects. I might be able to get around this by using the SeekHeader and making it the focus, but that offers its own challenges...
I've tried using the colParagraph.Range.Font.Underline object, but that underlines the entire line, not just the words that make up the column headings.
I've tried using a find object, but the execute doesn't find the text for some reason.
Appreciate any guidance you can provide.
I had to move the set style above the for loop and set a new range based on the paragraph range and move its start and end positions. Then apply the underlining to the new range.
So now it looks similar to ....
colParagraph.Range.InsertAfter(MARKUP_WORD_TAB);
colParagraph = wordRng.Paragraphs.Last; //reset the range to include the tab so the style can be applied.
colParagraph.set_Style(wordDoc.Styles["ColumnHeadings"]);
int year;
int start = colParagraph.Range.Text.Length - 1;
string yrHeading = string.Empty;
Word.Range underlineRange = null;
for (int i = 0 ; i < fiscalYears.Length; i++)
{
year = fiscalYears[i];
colParagraph = wordRng.Paragraphs.Last; //reset the range to include the last fiscal year that was entered.
start = colParagraph.Range.Text.Length - 1;
colParagraph.Range.InsertAfter(yrHeading);
colParagraph.Range.InsertAfter(MARKUP_WORD_TAB);
underlineRange = colParagraph.Range.Duplicate;
underlineRange.MoveStart(Word.WdUnits.wdCharacter, start);
underlineRange.MoveEnd(Word.WdUnits.wdCharacter, -2); //-2 = /t/r for tab & paragraph characters
underlineRange.Font.Underline = Word.WdUnderline.wdUnderlineSingle;
}
colParagraph = wordRng.Paragraphs.Add();

Create word document and write formatted text

using Word = Microsoft.Office.Interop.Word;
public static void CreateWord()
{
Word.Application objWord = new Word.Application();
Word.Document objDoc = objWord.Documents.Add();
Word.Paragraph objPara;
objPara = objDoc.Paragraphs.Add();
objPara.Range.Text = "Bold text aligned center";
objPara.Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
objPara.Range.Bold = 1;
objPara.Range.InsertParagraphAfter();
objPara = objDoc.Paragraphs.Add();
objPara.Range.Text = "Regular text aligned left";
objPara.Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
objPara.Range.Bold = 0;
objPara.Range.InsertParagraphAfter();
objPara = objDoc.Paragraphs.Add();
objPara.Range.Text = "Regular text aligned center\nwith something on the next line";
objPara.Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
objPara.Range.Bold = 0;
objPara.Range.InsertParagraphAfter();
objPara = objDoc.Paragraphs.Add();
objPara.Range.Text = "Regular text aligned left, with some Bold text here\nand some regular text on next line";
objPara.Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
objPara.Range.Bold = 0;
objPara.Range.InsertParagraphAfter();
objWord.Visible = true;
objWord.WindowState = Word.WdWindowState.wdWindowStateNormal;
}
The code above creates a Word document and writes text to it, but it looks like this:
I'm assuming that text in Microsoft.Office.Interop.Word is not supposed to act like that, or text should be added in some other way, but I'm failing to find any good information on how to do this.
So, my question is - how to add text from c# to a newly created word document with the right properties, so the result looks like this:
P.S. tips about creating tables using .Interop.Word would also be appreciated.
The key to working with content in Word documents is to understand how to work with Range objects. There's more than one way to achieve a goal of this nature. The following code snippet is my preference: collapsing the Range for each step (think of it like pressing the right-arrow key to "collapse" a selection to a point), rather than mixing Add, InsertAfter and similar methods.
For each change of formatting the Range must be "collapsed". So if you have bold in the middle of a line, that's a separate step. If numerous paragraphs should have the same formatting, they can be combined.
Environment.NewLine and \n can be used interchangeably.
Generally, assign text content, then format the Range.
object oCollapseEnd = Word.WdCollapseDirection.wdCollapseEnd;
doc.Paragraphs.Add();
Word.Range objRange = doc.Content;
objRange.Collapse(ref oCollapseEnd);
objRange.Text = "Bold text aligned center" + Environment.NewLine;
objRange.Bold = 1;
objRange.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
objRange.Collapse(ref oCollapseEnd);
objRange.Text = "Regular text aligned left" + Environment.NewLine;
objRange.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
objRange.Bold = 0;
objRange.Collapse(ref oCollapseEnd);
objRange.Text = "Regular text aligned center\nwith something on the next line" + Environment.NewLine;
objRange.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
objRange.Bold = 0;
objRange.Collapse(ref oCollapseEnd);
objRange.Text = "Regular text aligned left, with some ";
objRange.Collapse(ref oCollapseEnd);
objRange.Text = "Bold text here";
objRange.Bold = 1;
objRange.Collapse(ref oCollapseEnd);
objRange.Text = "\nand some regular text on next line" + Environment.NewLine;
objRange.Paragraphs.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft;
objRange.Bold = 0;

C# losing Font Style in RichTextBox after deleting lines

I have a RichTextBox for a simple chat where I add lines programmatically.
I make the usernames bold and the messages in regular style.
After some lines I want to delete the first lines to keep the chat in a acceptably length. But when I do so I lose the text format and everything appears bold. What am I doing wrong and how can I fix this?
EDIT
I could solve the problem where I wasn't able to delete the first line.
I had to set the the ReadOnly property to false. Even though I was able to add new lines it prevented deleting lines. So the following code works to delete lines. Thanks to #TaW!
if (ChatText.Lines.Length >= 10)
{
int p = 0; int count = 0;
do
{
p = ChatText.Text.IndexOf("\n\r");
if (p >= 0)
{
ChatText.SelectionStart = p;
ChatText.SelectionLength = 2; // length of "\n\r"
ChatText.SelectedText = "\n";
count++;
}
}
while(p >= 0);
int nll = 1; // <<=== pick the length of your new line character(s)!!
int pS = ChatText.Lines.Take(0).Select(x => x.Length + nll).Sum() - nll;
int pL = ChatText.Lines.Take(1).Select(x => x.Length + nll).Sum() - nll;
if (pS < 0) { pS = 0; pL++; }
ChatText.SelectionStart = pS;
ChatText.SelectionLength = pL - pS;
ChatText.Cut();
}
//////////////////////////////////
// now add new lines
//////////////////////////////////
string[] chatstr;
// string text is given as method parameter
chatstr = text.Split(new string[] { ": " }, 2, StringSplitOptions.None);
// go to the end of the text
ChatText.SelectionStart = ChatText.Text.Length;
ChatText.SelectionLength = 0;
// make text bold
ChatText.SelectionFont = new Font(ChatText.Font, FontStyle.Bold);
// add username (chatstr[0]) and colon
ChatText.AppendText(chatstr[0] + ": ");
// make text regular
ChatText.SelectionFont = new Font(ChatText.Font, FontStyle.Regular);
// add message (chatstr[1])
ChatText.AppendText(chatstr[1] + "\n");
// and finaly scroll down
ChatText.ScrollToCaret();
So deleting lines works and new lines are added as intended. Finaly!
solved :)
Never change the Text of a RichtTextBox if it contains any formatting.
Changing the Lines property (by Skip) is just another way to change the Text.
Instead only use the functions the RTB provides: Always start by selecting the portion you want to format, then apply one or more of the functions and/or set one or more of the properties..:
To delete portions use Cut.
Here is a function that will delete a number of entire lines:
void DeleteLines(RichTextBox rtb, int fromLine, int count)
{
int p1 = rtb.GetFirstCharIndexFromLine(fromLine);
int p2 = rtb.GetFirstCharIndexFromLine(fromLine + count);
rtb.SelectionStart = p1;
rtb.SelectionLength = p2 - p1;
bool readOnly = rtb.ReadOnly; // allow change even when the RTB is readonly
rtb.ReadOnly = false; ;
rtb.Cut();
rtb.ReadOnly = readOnly;
}
Trying to keept the formatting alive yourself is a tedious and error-prone waste of your time.
In addition to font properties you would also have to resore all other things you can set with the SelectedXXX properties, like colors, alignment, spacing etc etc..
To delete the first 3 lines use:
DeleteLines(yourRTB, 0, 3);
To restrict the text to 10 lines use:
DeleteLines(yourRTB, 0, yourRTB.Lines.Length - 10);
Note that the function above should have a few checks for valid input; I left them out as the checks somehow need a decision what to do, if count or fromLine if greater than Lines.Length or if fromLine is negative..
While we are at it, here is how to append a bold line:
yourRTB.SelectionStart = yourRTB.Text.Length;
yourRTB.SelectionLength = 0;
using (Font font = new Font(yourRTB.SelectionFont, FontStyle.Bold))
yourRTB.SelectionFont = font;
yourRTB.AppendText(yourNewLine + textOfNewLine);
Of course it really shold go into a reuseable function that the the bolding as a parameter..
Update:
since you are using WordWrap you may prefer this function. It deletes the actual lines, not the visible ones:
void DeleteLinesWW(RichTextBox rtb, int fromLine, int count)
{
int nll = 1; // <<=== pick the length of your new line character(s)!!
int pS = rtb.Lines.Take(fromLine).Select(x => x.Length + nll).Sum() - nll;
int pL = rtb.Lines.Take(fromLine + count).Select(x => x.Length + nll).Sum() - nll;
if (pS < 0) { pS = 0; pL++; }
rtb.SelectionStart = pS;
rtb.SelectionLength = pL - pS ;
bool readOnly = rtb.ReadOnly;
rtb.ReadOnly = false; // allow change even when the RTB is readonly
rtb.Cut();
rtb.ReadOnly = readOnly;
}
A word on NewLine: Do note that I have not used the Environment.NewLine constant as it not really a good idea. If you add multiline text to the RichTextBox in the designer and then look at it you will see that it uses simple '\n' new lines, no returns, no NL-CR, just '\n'. So this seems to be the generic way in a winforms RTB and I recommend using it..
The new function relies on all lines having a newline of the same length!
To make sure you can use this replacement function:
int RTBReplace(RichTextBox rtb, string oldText, string newText)
{
int p = 0; int count = 0;
do
{
p = richTextBox1.Text.IndexOf(oldText);
if (p >= 0)
{
richTextBox1.SelectionStart = p;
richTextBox1.SelectionLength = oldText.Length;
richTextBox1.SelectedText = newText;
count ++;
}
}
while (p >= 0);
return count;
}
Calling it like this:
RTBReplace(yourrichTextBox, "\r\n", "\n");
Update 2:
Here is an example how to add your chat lines:
private void button1_Click(object sender, EventArgs e)
{
string cLine = "Taw: Hello World"; // use your own lines!
var chatstr = cLine.Split(new string[] { ": " }, 2, StringSplitOptions.None);
AppendLineBold(yourrichTextBox, "\n" + chatstr[0], true);
AppendLineBold(yourrichTextBox, chatstr[1], false);
yourrichTextBox.ScrollToCaret();
}
void AppendLineBold(RichTextBox rtb, string text, bool bold)
{
rtb.SelectionStart = richTextBox1.Text.Length;
rtb.SelectionLength = 0;
using (Font font = new Font(rtb.SelectionFont,
bold ? FontStyle.Bold : FontStyle.Regular))
rtb.SelectionFont = font;
rtb.AppendText(text);
}
Update 3:
Looks like the ReadOnly property disallows the use of Cut. So we need to temporatily allow changes.
Funny: SelectedText can't be set either, but AppendText works fine..
To keep text formatting, you can also try the following (it's a little shorter and should also do the trick)
string text = "Username: hello this is a chat message";
// delete the first line when after 10 lines
if (ChatText.Lines.Length >= 10)
{
ChatText.SelectionStart = 0; // set SelectionStart to the beginning of chat text (RichTextBox)
ChatText.SelectionLength = ChatText.Text.IndexOf("\n", 0) + 1; // select the first line
ChatText.SelectedText = ""; // replace by an empty string
ChatText.SelectionStart = ChatText.Text.Length; // set SelectionStart to text end to make SelectionFont work for appended text
}
// split the string in chatstr[0] = username, chatstr[1] = message
string[] chatstr = text.Split(new string[] { ": " }, 2, StringSplitOptions.None);
// make the username bold
ChatText.SelectionFont = new Font(ChatText.Font, FontStyle.Bold);
ChatText.AppendText(chatstr[0] + ": ");
// make the message regular
ChatText.SelectionFont = new Font(ChatText.Font, FontStyle.Regular);
ChatText.AppendText(chatstr[1] + Environment.NewLine);
ChatText.ScrollToCaret();

iTextSharp multiple lines in PdfPCell one under another

I am using iTextSharp to create table in PDF document. I need several lines inside table cell to appear one under another like this:
First line text
Second Line Text
Third Line Text
Fourth line text
Some times with extra line like this :
First line text
Second Line Text
Third Line Text
Fourth line text
I have tried several approaches, with Paragraphs, Chunks, Phrases, did research online but still can not get this result. Please help.
Also, how to make columns to adjust width dynamically to content ? (not wrapping)
Thank you
If you need to align at the text level you'll need to switch to a fixed-width font. But if you're just looking to indent you can just add spaces to new lines within a paragraph:
var p = new Paragraph();
p.Add("First line text\n");
p.Add(" Second line text\n");
p.Add(" Third line text\n");
p.Add("Fourth line text\n");
myTable.AddCell(p);
You could also get complicated and use a sub-table if you need more control:
var subTable = new PdfPTable(new float[] { 10, 100 });
subTable.AddCell(new PdfPCell(new Phrase("First line text")) { Colspan = 2, Border = 0 });
subTable.AddCell(new PdfPCell() { Border = 0 });
subTable.AddCell(new PdfPCell(new Phrase("Second line text")) { Border = 0 });
subTable.AddCell(new PdfPCell() { Border = 0 });
subTable.AddCell(new PdfPCell(new Phrase("Third line text")) { Border = 0 });
subTable.AddCell(new PdfPCell(new Phrase("Fourth line text")) { Colspan = 2, Border = 0 });
myTable.AddCell(subTable);
Though pretty tedious, but for setting font, following seem to work:
Font myFont = FontFactory.GetFont("Arial", 8, Font.NORMAL);
string line1 = "First line of text" + "\n";
string line2= "Second line of text" + "\n";
string line3= " Third Line of text";
Paragraph p1 = new Paragraph();
Phrase ph1 = new Phrase(line1, myFont);
Phrase ph2 = new Phrase(line2, myFont);
Phrase ph3 = new Phrase(line3, myFont);
p1.Add(ph1);
p1.Add(ph2);
p1.Add(ph3);
PdfPCell mycell = new PdfPCell(p1);
You can also do it the following way ..
var xstring = "Your first line \n Your 2nd line";
Phrase p = new Phrase();
p.Add(new Chunk(xstring, yourFontFace));
I text will notice the new line return code and render your phrase on two separate lines.
Your first line
Your 2nd line
Cheers
#region .!!
PdfPTable tbl_A = new PdfPTable(1);
tbl_A.WidthPercentage = 98f;
//float[] colWidthUnderTaking1 = { 1300 };
//tblUnderTaking1.SetWidths(colWidthUnderTaking1);
#region For Page Space
PdfPCell cell_A;
cell_A = new PdfPCell(new Phrase(" ", Smallspace));
cell_A.HorizontalAlignment = 1;
cell_A.BorderWidth = 0;
cell_A.Colspan = 2;
tbl_A.AddCell(cell_A);
cell_A = new PdfPCell(new Phrase(" ", Smallspace));
cell_A.HorizontalAlignment = 1;
cell_A.BorderWidth = 0;
cell_A.Colspan = 2;
tbl_A.AddCell(cell_A);
#endregion
Chunk cMem = new Chunk("The Member ", TableFontmini_ARBold8Nor);
Chunk cName = new Chunk(dt.Rows[0]["EmpName"].ToString(), TableFontmini_ARBold10);
Chunk cjoin = new Chunk(" Has joined On ", TableFontmini_ARBold8Nor);
Chunk cDOJ = new Chunk(" " + dt.Rows[0]["DOJPF"].ToString(), TableFontmini_ARBold10);
Chunk chas = new Chunk("and has been alloted PF Member ID ", TableFontmini_ARBold8Nor);
Chunk cPF = new Chunk(" " + dt.Rows[0]["PFNo"].ToString(), TableFontmini_ARBold10);
Phrase paira = new Phrase();
paira.Add(cMem);
paira.Add(cName);
paira.Add(cjoin);
paira.Add(cDOJ);
paira.Add(chas);
paira.Add(cPF);
Paragraph pName = new Paragraph();
pName.Add(paira);
PdfPCell cell_A2 = new PdfPCell(pName);
cell_A2.HorizontalAlignment = 0;/**Left=0,Centre=1,Right=2**/
cell_A2.BorderWidth = 0;
cell_A2.Colspan = 2;
tbl_A.AddCell(cell_A2);
doc.Add(tbl_A);
#endregion

Categories

Resources