DataTable in FlowDocument - c#

I am trying to create a flowdocument with a Table of data which I want to print on the printer. I can create the flowdocument and the printer stuff, but I don't know how to create the table.
Here is my code:
//Creating flow document
Paragraph myParagraph = new Paragraph();
//Add content to the paragraph
myParagraph.Inlines.Add(new Bold(new Run("List of tasks (" + TasksToShow.Count + ")")));
//Create content of paragraph
DataTable myTable = new DataTable();
myTable.Columns.Add("Task ID", typeof(int));
myTable.Columns.Add("Task name", typeof(string));
foreach (Task task in TasksToShow)
{
myTable.Rows.Add(task.TaskID, task.TaskName);
}
//Adding content to the flow document
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
myFlowDocument.Blocks.Add(myTable); //This line fails :(
//Print the document
PrintDialog dialog = new PrintDialog();
if(dialog.ShowDialog() == true)
{
int margin = 5;
Size pageSize = new Size(dialog.PrintableAreaWidth - margin * 2, dialog.PrintableAreaHeight - margin * 2);
IDocumentPaginatorSource paginator = myFlowDocument;
paginator.DocumentPaginator.PageSize = pageSize;
dialog.PrintDocument(paginator.DocumentPaginator, "Flow print");
}

you can do like this.....
// Create the parent FlowDocument...
flowDoc = new FlowDocument();
// Create the Table...
table1 = new Table();
// ...and add it to the FlowDocument Blocks collection.
flowDoc.Blocks.Add(table1);
// Set some global formatting properties for the table.
table1.CellSpacing = 10;
table1.Background = Brushes.White;
pls go through this links for more info
after that you can change this depnds upon the your requirement...

Related

MigraDoc table formatting / cell indent

I'm trying to create a table with MigraDoc. I want it to look like this:
This is how the table should look
Instead I'm only getting this:
This is the table I'm getting
The text is too near to the border. The indent is missing. I tried
table.Format.LeftIndent = 0.2;
and
table.Format.LeftIndent = "0,2cm";
to set the indent for all table cells. But it didn't work. How can an indent for all table cells be achieved?
This is my complete test method:
private Document debugMigraDocTable()
{
Document document = setupDocument();
Section sectionProtocolHeader = document.AddSection();
Paragraph measValueParagraph = sectionProtocolHeader.AddParagraph("Measurement");
Table table = sectionProtocolHeader.AddTable();
table.Format.LeftIndent = 0.8;
// Table header
Column column = table.AddColumn("1,2cm");
column = table.AddColumn("1,7cm");
column = table.AddColumn("1,7cm");
column = table.AddColumn("1,2cm");
column = table.AddColumn("1,7cm");
column = table.AddColumn("1,7cm");
Row row = table.AddRow();
row.HeadingFormat = true;
row.Format.Alignment = ParagraphAlignment.Center;
row.Format.Font.Bold = true;
row.Cells[0].AddParagraph("Key");
row.Cells[1].AddParagraph("Value 1");
row.Cells[2].AddParagraph("Value 2");
row.Cells[3].AddParagraph("Key");
row.Cells[4].AddParagraph("Value 1");
row.Cells[5].AddParagraph("Value 2");
// Table data
row = table.AddRow();
row.Cells[0].AddParagraph("1");
row.Cells[1].AddParagraph("1,13");
row.Cells[2].AddParagraph("");
row.Cells[3].AddParagraph("33");
row.Cells[4].AddParagraph("0,84");
row.Cells[5].AddParagraph("");
row = table.AddRow();
row.Cells[0].AddParagraph("2");
row.Cells[1].AddParagraph("1,19");
row.Cells[2].AddParagraph("");
row.Cells[3].AddParagraph("34");
row.Cells[4].AddParagraph("1,35");
row.Cells[5].AddParagraph("");
row = table.AddRow();
row.Cells[0].AddParagraph("3");
row.Cells[1].AddParagraph("1,01");
row.Cells[2].AddParagraph("");
row.Cells[3].AddParagraph("35");
row.Cells[4].AddParagraph("1,28");
row.Cells[5].AddParagraph("");
return document;
}
For preview and printing I render this to RTF:
Document document = debugMigraDocTable();
RtfDocumentRenderer rtfRenderer = new RtfDocumentRenderer();
string rtf = rtfRenderer.RenderToString(document, Path.GetTempPath());

WPF: The font will not change on a printed FlowDocument

I am trying to print the contents of a rich-text box. I do that in the following way:
Obtain a TextRange from the FlowDocument.
Create a new FlowDocument with a smaller font using the TextRange.
Send this new FlowDocument to the printer.
My problem, is that the font doesn't seem to change. I would like it to go down to size 8. Instead, it remains at a fixed size. Here is my code:
private void button_Print_Click(object sender, RoutedEventArgs e)
{
IDocumentPaginatorSource ps = null;
FlowDocument fd = new FlowDocument();
PrintDialog pd = new PrintDialog();
Paragraph pg = new Paragraph();
Style style = new Style(typeof(Paragraph));
Run r = null;
string text = string.Empty;
// get the text
text = new TextRange(
this.richTextBox_Info.Document.ContentStart,
this.richTextBox_Info.Document.ContentEnd).Text;
// configure the style of the flow document
style.Setters.Add(new Setter(Block.MarginProperty, new Thickness(0)));
fd.Resources.Add(typeof(Paragraph), style);
// style the paragraph
pg.LineHeight = 0;
pg.LineStackingStrategy = LineStackingStrategy.BlockLineHeight;
pg.FontFamily = new FontFamily("Courier New");
pg.TextAlignment = TextAlignment.Left;
pg.FontSize = 8;
// create the paragraph
r = new Run(text);
r.FontFamily = new FontFamily("Courier New");
r.FontSize = 8;
pg.Inlines.Add(r);
// add the paragraph to the document
fd.Blocks.Add(pg);
ps = fd;
// format the page
fd.PagePadding = new Thickness(50);
fd.ColumnGap = 0;
fd.ColumnWidth = pd.PrintableAreaWidth;
// print the document
if (pd.ShowDialog().Value == true)
{
pd.PrintDocument(ps.DocumentPaginator, "Information Box");
}
}
I would like to add that, changing the font works just fine for the flow-document when it is inside of the rich-text box. However, when I am doing it programmatically (as shown above) I run into problems.
I try your code and found when I remove this line and then change the r.FontSize to 50, it seems work.
pg.LineHeight = 0;

WPF FlowDocument printing only to small area

I am printing plain text in WPF by using a FlowDocument, FlowDocumentPaginator and PrintDialog. My approach is based on this article and is implemented as follows:
var printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
{
var flowDocument = new FlowDocument();
var paragraph = new Paragraph();
paragraph.FontFamily = new FontFamily("Courier New");
paragraph.FontSize = 10;
paragraph.Margin = new Thickness(0);
paragraph.Inlines.Add(new Run(this.textToPrint));
flowDocument.FontSize = 10;
flowDocument.Blocks.Add(paragraph);
var paginator = ((IDocumentPaginatorSource)flowDocument).DocumentPaginator;
printDialog.PrintDocument(paginator, "Chit");
}
This works good for printing stuff with narrow width. But when I try to print a long string, it all gets stuffed in a small area:
I checked dimensions in the print dialog's PrintTicket and in the paginator, and they seem to be okay:
So, what is causing this problem and how can I fix it?
This is some code I use
flowDocument.PagePadding = new Thickness(standardThickness);
flowDocument.ColumnGap = 0;
flowDocument.ColumnWidth = printDialog.PrintableAreaWidth;
You need to tell the flowdocument it is one column and tell the flowdocument the width of the printer.

Adding a new page using iTextSharp

I have a class that build the content for my table of contents and that works, fine and dandy.
Here's the code:
public void Build(string center,IDictionary<string,iTextSharp.text.Image> images)
{
iTextSharp.text.Image image = null;
XPathDocument rapportTekst = new XPathDocument(Application.StartupPath + #"..\..\..\RapportTemplates\RapportTekst.xml");
XPathNavigator nav = rapportTekst.CreateNavigator();
XPathNodeIterator iter;
iter = nav.Select("//dokument/brevhoved");
iter.MoveNext();
var logo = iTextSharp.text.Image.GetInstance(iter.Current.GetAttribute("url", ""));
iter = nav.Select("//dokument/gem_som");
iter.MoveNext();
string outputPath = iter.Current.GetAttribute("url", "")+center+".pdf";
iter = nav.Select("//dokument/titel");
iter.MoveNext();
this.titel = center;
Document document = new Document(PageSize.A4, 30, 30, 100, 30);
var outputStream = new FileStream(outputPath, FileMode.Create);
var pdfWriter = PdfWriter.GetInstance(document, outputStream);
pdfWriter.SetLinearPageMode();
var pageEventHandler = new PageEventHandler();
pageEventHandler.ImageHeader = logo;
pdfWriter.PageEvent = pageEventHandler;
DateTime timeOfReport = DateTime.Now.AddMonths(-1);
pageWidth = document.PageSize.Width - (document.LeftMargin + document.RightMargin);
pageHight = document.PageSize.Height - (document.TopMargin + document.BottomMargin);
document.Open();
var title = new Paragraph(titel, titleFont);
title.Alignment = Element.ALIGN_CENTER;
document.Add(title);
List<TableOfContentsEntry> _contentsTable = new List<TableOfContentsEntry>();
nav.MoveToRoot();
iter = nav.Select("//dokument/indhold/*");
Chapter chapter = null;
int chapterCount = 1;
while (iter.MoveNext())
{
_contentsTable.Add(new TableOfContentsEntry("Test", pdfWriter.CurrentPageNumber.ToString()));
XPathNodeIterator innerIter = iter.Current.SelectChildren(XPathNodeType.All);
chapter = new Chapter("test", chapterCount);
while(innerIter.MoveNext())
{
if (innerIter.Current.Name.ToString().ToLower().Equals("billede"))
{
image = images[innerIter.Current.GetAttribute("navn", "")];
image.Alignment = Image.ALIGN_CENTER;
image.ScaleToFit(pageWidth, pageHight);
chapter.Add(image);
}
if (innerIter.Current.Name.ToString().ToLower().Equals("sektion"))
{
string line = "";
var afsnit = new Paragraph();
line += (innerIter.Current.GetAttribute("id", "") + " ");
innerIter.Current.MoveToFirstChild();
line += innerIter.Current.Value;
afsnit.Add(line);
innerIter.Current.MoveToNext();
afsnit.Add(innerIter.Current.Value);
chapter.Add(afsnit);
}
}
chapterCount++;
document.Add(chapter);
}
document = CreateTableOfContents(document, pdfWriter, _contentsTable);
document.Close();
}
I'm then calling the method CreateTableOfContents(), and as such it is doing what it is supposed to do. Here's the code for the method:
public Document CreateTableOfContents(Document _doc, PdfWriter _pdfWriter, List<TableOfContentsEntry> _contentsTable)
{
_doc.NewPage();
_doc.Add(new Paragraph("Table of Contents", FontFactory.GetFont("Arial", 18, Font.BOLD)));
_doc.Add(new Chunk(Environment.NewLine));
PdfPTable _pdfContentsTable = new PdfPTable(2);
foreach (TableOfContentsEntry content in _contentsTable)
{
PdfPCell nameCell = new PdfPCell(_pdfContentsTable);
nameCell.Border = Rectangle.NO_BORDER;
nameCell.Padding = 6f;
nameCell.Phrase = new Phrase(content.Title);
_pdfContentsTable.AddCell(nameCell);
PdfPCell pageCell = new PdfPCell(_pdfContentsTable);
pageCell.Border = Rectangle.NO_BORDER;
pageCell.Padding = 6f;
pageCell.Phrase = new Phrase(content.Page);
_pdfContentsTable.AddCell(pageCell);
}
_doc.Add(_pdfContentsTable);
_doc.Add(new Chunk(Environment.NewLine));
/** Reorder pages so that TOC will will be the second page in the doc
* right after the title page**/
int toc = _pdfWriter.PageNumber - 1;
int total = _pdfWriter.ReorderPages(null);
int[] order = new int[total];
for (int i = 0; i < total; i++)
{
if (i == 0)
{
order[i] = 1;
}
else if (i == 1)
{
order[i] = toc;
}
else
{
order[i] = i;
}
}
_pdfWriter.ReorderPages(order);
return _doc;
}
The problem is however. I want to insert a page break before the table of contents, for the sake of reordering the pages, so that the table of contents is the first page, naturally. But the output of the pdf-file is not right.
Here's a picture of what it looks like:
It seems like the _doc.NewPage() in the CreateTableOfContents() method does not execute correctly. Meaning that the image and the table of contents is still on the same page when the method starts the reordering of pages.
EDIT: To clarify the above, the _doc.NewPage() gets executed, but the blank page is added after the picture and the table of contents.
I've read a couple of places that this could be because one is trying to insert a new page after an already blank page. But this is not the case.
I'll just link to the pdf files aswell, to better illustrate the problem.
The pdf with table of contents: with table of contents
The pdf without table of contents: without table of contents
Thank you in advance for your help :)

How to get rid of my "After Spacing" on open xml

In open XML my word document defaults to having "Spacing After: 10 pt" How would I change it to 0, so there is no spacing.
Here is my code, which pretty much grabs the information from a database and places it onto a word document to be able to print out. But the spacing is making the document too big.
using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document)) {
MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
Paragraph para_main = body.AppendChild(new Paragraph());
Run run_main = para_main.AppendChild(new Run());
// Goes through all of the forms
foreach (var form in forms) {
Table table = new Table();
// Initialize all of the table properties
TableProperties tblProp = new TableProperties(
new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.BasicBlackSquares), Size = 16 },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.BasicBlackSquares), Size = 16 },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.BasicBlackSquares), Size = 16 },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.BasicBlackSquares), Size = 16 },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.BasicBlackSquares), Size = 8 },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.BasicBlackSquares), Size = 8 }
),
new SpacingBetweenLines() { Before = "20", After = "20" }
//new TableCellProperties(
// new
//new TableJustification() {Val = TableRowAlignmentValues.Center}
);
table.AppendChild<TableProperties>(tblProp);
Paragraph para_header = body.AppendChild(new Paragraph());
Run run_header = para_header.AppendChild(new Run());
RunProperties runProps = run_header.AppendChild(new RunProperties(new Bold()));
string username = form.Username;
string proces_header = form.HeaderTitle;
run_header.AppendChild(new Text(proces_header + " | " + username));
for (int i = 0; i < form.FieldList.Count; i++) {
if (!(form.FieldList[i].Token == "USR" || form.FieldList[i].Token == "SNT")) {
TableRow tr = new TableRow();
TableCell header_cell = new TableCell();
header_cell.Append(new Paragraph(new Run(new Text(form.FieldList[i].Label))));
TableCell value_cell = new TableCell();
value_cell.Append(new Paragraph(new Run(new Text(form.FieldList[i].Value))));
tr.Append(header_cell, value_cell);
table.Append(tr);
}
}
wordDoc.MainDocumentPart.Document.Body.Append(table);
}
mainPart.Document.Save();
wordDoc.Close();
return "Success";
}
The line spacing needs to be appended to the paragraph properties and of course that needs to be appended to the paragraph.
Here is the long way to do it. The SpacingBetweenLines can also set the line height and the "rules" control how the before and after values are used.
SpacingBetweenLines spacing = new SpacingBetweenLines() { Line = "240", LineRule = LineSpacingRuleValues.Auto, Before = "0", After = "0" };
ParagraphProperties paragraphProperties = new ParagraphProperties();
Paragraph paragraph = new Paragraph();
paragraphProperties.Append(spacing);
paragraph.Append(paragraphProperties);
It looks like you are trying to set the line spacing to the table. That will not work that way(believe me I tried). Text around the table is controlled by the text wrapping and the positioning of the table.
Also when working with multiple tables, if you want to keep them separated there needs to be a paragraph(or something other then a table) after the table, otherwise your tables we merge together.
If you need that space create a paragraph with the font set to .5 or something really small and just add it after each table.

Categories

Resources