I have a text box within a footer in a Word doc. It has some template text that is left-aligned, and then already has the "Page x of n" right-aligned. When I try and replace the template text, all of the text is replaced.
Using C# or VB (either way) I need to replace the text inside of the text box (all of this text should be left-aligned) and then add "Page x of n" (right-aligned).
Here is what I have so far as a test:
string footer;
foreach (Shape shape in oMyDoc.Sections[1].Footers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Shapes)
{
footer = shape.TextFrame.ContainingRange.Text;
footer = footer.Replace("\r", "");
footer = footer.Replace("[Quote Type]", "Big Quote");
footer = footer.Replace("(", "\u2022");
int start = footer.IndexOf("Pager ");
footer = footer.Remove(start + 5);
var numPages = oMyDoc.ComputeStatistics(WdStatistic.wdStatisticPages);
footer = footer + " of " + numPages.ToString();
shape.TextFrame.ContainingRange.Text = footer;
}
Related
We are working with forms and in current project we are working with NPOI object but due to word metadata npoi is not returning the first,even and odd page Headers/footers. So we are trying with interop for getting the correct results and we are able to get the results as per the below code. But again we are facing the challenge with reading bodyelements in sequence order which are under headers/footers.
Current Result:
I am able to read the body elements(table and paragraph) of header/footer. But not in sequence order. I can able to read the elements individually like "firstPageFooter .Paragraphs" and "firstPageFooter .Tables"
foreach (Section data in sections)
{
var tempVal = string.Empty;
HeadersFooters headersFooters = data.Footers;
bool isDifferentFirstPageHeaderFooter = Convert.ToBoolean(data.PageSetup.DifferentFirstPageHeaderFooter);
bool isOddAndEvenPagesHeaderFooter = Convert.ToBoolean(data.PageSetup.OddAndEvenPagesHeaderFooter);
if (isDifferentFirstPageHeaderFooter)
firstPageFooter = headersFooters[WdHeaderFooterIndex.wdHeaderFooterFirstPage].Range;
Tables headerTable = firstPageFooter .Tables;
StringBuilder tableBuilder = new StringBuilder();
foreach (Table table in headerTable)
{
foreach (Row row in table.Rows)
{
foreach (Cell cell in row.Cells)
{
tableBuilder.Append(cell.Range.Text);
}
}
}
StringBuilder paraBuilder = new StringBuilder();
var headerPara= firstPageFooter.Paragraphs;
foreach (Paragraph paragraph in headerPara)
{
paraBuilder.Append(paragraph.Range.Text);
}
} // Added by edit!!!
Expected Results:
If the header/Footer body elements contains tables and paragraph. First element is table and second is paragraph. So the word should return the body elements in the same sequence order.
Can some one help me out?
It's possible to loop the Paragraphs collection of the document Story (a Header, for example) and test whether it's in a table. If it is, then pick up the table and process it. Then continue with the paragraph below the table, until the Story has been completed.
Here's a code snippet that demonstrates this approach, based on a single Header.
Word.HeaderFooter hdr = doc.Sections[1].Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary];
Word.Range hdrRange = hdr.Range;
Word.Paragraphs paras = hdrRange.Paragraphs;
for (int counter = 1; counter <= paras.Count; counter++)
{
Word.Paragraph para = paras[counter];
if ((bool)para.Range.get_Information(Word.WdInformation.wdWithInTable))
{
//Get the table that belongs to the first paragraph in the table
Word.Table tbl = para.Range.Tables[1];
//Reset the counter so that it cycles to the paragraph after the table
counter += tbl.Range.Paragraphs.Count - 1;
Debug.Print("In table with " + (counter - 1).ToString() + " paragraphs");
//Process the table
}
else
{
//Process the paragraph
Debug.Print("Paragraph " + counter.ToString() + ": " + para.Range.Text);
}
}
I have a Single line text box and Multiline text box, and want to include a word into the Single line text box with the words in Multiline text box per line
Like this :
Single line text: "Hello"(I have to use variables)<br>
Multiline words:
<br>
1998<br>
1999<br>
2000
Expected results:
Hello1998
Hello1999
Hello2000
Pls Help me
I use the below code, but it is not working just with the Single line text box and I have to manipulate by both text boxes:
string left = string.Format(add.Text , Environment.NewLine);
string right = string.Format(textBox1.Text, Environment.NewLine);
string[] leftSplit = left.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
string[] rightSplit = right.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
string output = "";
if (leftSplit.Length == rightSplit.Length)
{
for (int i = 0; i < leftSplit.Length; i++)
{
output += leftSplit[i] + ":" + rightSplit[i] + Environment.NewLine;
}
}
result.Text = output;
Could you please advise me on the right approach?
If you have single line only one word, then no need split it into an array.
Lets consider it as a string left = "Hello";
and textbox1 contains multiline words i.e.
string right = string.Format(textBox1.Text, Environment.NewLine); // right variable contains 1998 \n 1999 \n 2000
Then you can try below approach
var concatString = right.Split(new[] { Environment.NewLine }, StringSplitOptions.None).Select(x => left + x);
string result = string.Join(Environment.NewLine , concatString);
.Net Fiddle
Output :
Hello1998
Hello1999
Hello2000
TextBox.GetLineText(int) will help you:
var singlelineText = singlelineTextBox.Text;
var composedLines = new List<string>();
for (var i = 0; i < multilineineTextBox.LineCount; i++)
{
composedLines.Add(singlelineText + multilineineTextBox.GetLineText(i));
}
result.Text = string.Join(EnvironmentNewline, composedLines);
I use Microsoft.Office.Interop.Word to get words from Word file and then I populate it into a table layout panel. Unfortunately, the words displayed at the table layout panel are not following exact sequence as in the Word file.
How to fix this?
// Open a doc file.
Microsoft.Office.Interop.Word.Application application = new Microsoft.Office.Interop.Word.Application();
Document d ocument = application.Documents.Open(txtUploadedPathToken.Text);
// Loop through all words in the document.
int count = document.Words.Count;
for (int i = 1; i <= count; i++)
{
// Write the word.
string text = document.Words[i].Text;
//Console.WriteLine("Word {0} = {1}", i, text);
tableLayoutPanel2.Controls.Add(new Label() { Text = text, Anchor = AnchorStyles.Left, AutoSize = true}, 0, 0);
}
Your word document reading code seems OK. but you may need to change how you add items to panel. Since you add new items to same position (0,0) it may give incorrect order.
foreach (Microsoft.Office.Interop.Word.Range range in document.Words)
{
string text = range.Text;
tableLayoutPanel2.Controls.Add(new Label() { Text = text, Anchor = AnchorStyles.Left, AutoSize = true});
}
I have a PDFP Table and I want to have it laid out like so:
Item1 ............ $10.00
Item1123123 ...... $50.00
Item3 ............ $75.00
This is what I have so far:
var tableFont = FontFactory.GetFont(FontFactory.HELVETICA, 7);
var items = from p in ctx.quote_server_totals
where p.item_id == id
&& p.name != "total"
&& p.type != "totals"
select p;
foreach (var innerItem in items)
{
detailsTable.AddCell(new Phrase(innerItem.type == "discount" ? "ADJUSTMENT -" + innerItem.name : innerItem.name, tableFont));
detailsTable.AddCell(new Phrase(".......................................................", tableFont));
detailsTable.AddCell(new Phrase(Convert.ToDecimal(innerItem.value).ToString("c"), tableFont));
}
document.Add(detailsTable);
As can see, the only way I've been able to get the dots to extend is by manually entering them; however, this obviously won't work because the the first column's width will be different every time I run this code. Is there a way I can accomplish this? Thanks.
Please download chapter 2 of my book and search for DottedLineSeparator. This separator class will draw a dotted line between two parts of a Paragraph (as shown in the figures in the book). You can find the C# version of the Java book samples here.
If you can use a fixed-width font such as FontFactory.COURIER your task will be a lot easier.
//Our main font
var tableFont = FontFactory.GetFont(FontFactory.COURIER, 20);
//Will hold the shortname from the database
string itemShortName;
//Will hold the long name which includes the periods
string itemNameFull;
//Maximum number of characters that will fit into the cell
int maxLineLength = 23;
//Our table
var t = new PdfPTable(new float[] { 75, 25 });
for (var i = 1; i < 10000; i+=100) {
//Get our item name from "the database"
itemShortName = "Item " + i.ToString();
//Add dots based on the length
itemNameFull = itemShortName + ' ' + new String('.', maxLineLength - itemShortName.Length + 1);
//Add the two cells
t.AddCell(new PdfPCell(new Phrase(itemNameFull, tableFont)) { Border = PdfPCell.NO_BORDER });
t.AddCell(new PdfPCell(new Phrase(25.ToString("c"), tableFont)) { Border = PdfPCell.NO_BORDER });
}
I have 2 paragraph objects that take up about 2/3 of the page. When I view it in the pdf the start of the 2nd paragraph starts on the 2nd page. Is there a way to start it on 1st page following the 1st paragraph?
PdfPTable rs1 = new PdfPTable(1);
PdfPCell c = new PdfPCell();
c.MinimumHeight = 36f;
Paragraph p = new Paragraph(
"some text to align\n" +
"..." +
"some text to align\n"
);
c.AddElement(p);
rs1.AddCell(c);
PdfPCell c2 = new PdfPCell();
c.MinimumHeight = 36f;
Paragraph p2 = new Paragraph(
"some text to align\n" +
"..." +
"some text to align\n" +
"some text to align\n"
);
p2.KeepTogether = false;
c2.AddElement(p2);
c2.VerticalAlignment = Element.ALIGN_TOP;
rs1.AddCell(c2);
return rs1;
I used PdfPTable.SplitLate = false
The issue isn't with your paragraphs but with your table. iTextSharp tries to not break content across table cells and your current layout appears to do that. Do you need to have a table? Regular paragraphs will just break when a line goes off the viewable area. If you need tables then you'll have to adjust the table's width if you can (rs1.WidthPercentage = 100;) and possibly any padding that you've set up.