PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Thu Mar 28, 2024 9:10 am

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Tue Nov 07, 2017 7:28 am 
Offline

Joined: Mon Nov 06, 2017 3:53 pm
Posts: 18
Hi, I think this is a rather easy problem to solve but I have yet not managed to do so.
I'm rather new to PDFsharp, so I use the code provided in your Wiki and modify it to meet my requirements.

I want the PDF to have on the first page a big header (i use a table for that). On all other pages the header will be different (smaller table).
However I did not manage to get the 'bodytext' to beign where I want. I tried to use margins but they only will be good for the first page. For the second page the margin will be too big and therefore space will be wasted on that page.
The worst case is setting the margin to fit for all other pages but the table on the first page will overlap with the 'bodytext'.

I made a C# WindowsForms application with just one form and one button. When the button is clicked, you guess it a pdf will be generated.
Here is my code so far:

Code:

private void cmdCreatePDF_click(object sender, EventArgs e)
{
Document document = CreateDocument();
MigraDoc.DocumentObjectModel.IO.DdlWriter.WriteToFile(document,"MigraDoc,mddl");
MigraDoc.Rendering.PdfDocumentRenderer renderer = new Migra.Redering.PdfRenderer(true, PdfSharp.Pdf.PdfFontEmbedding.Always);
renderer.Document = document;
renderer.RenderDocument();
string filename = @"C:\PdfSharp\mypdf.pdf";
renderer.PdfDocument.Save(filename);
}

private Document CreateDocument()
{
Document Doc = new Document()
Doc.Info.title = "TEST"

DefineStyles(Doc);
DefineContentSection(Doc);

return(Doc);
}

        private void DefineStyles(Document Doc)
        {
            // Get the predefined style Normal.
            Style style = Doc.Styles["Normal"];
            // Because all styles are derived from Normal, the next line changes the
            // font of the whole document. Or, more exactly, it changes the font of
            // all styles and paragraphs that do not redefine the font.
            style.Font.Name = "Times New Roman";

            // Heading1 to Heading9 are predefined styles with an outline level. An outline level
            // other than OutlineLevel.BodyText automatically creates the outline (or bookmarks)
            // in PDF.

            style = Doc.Styles["Heading1"];
            style.Font.Name = "Tahoma";
            style.Font.Size = 14;
            style.Font.Bold = true;
            style.Font.Color = Colors.DarkBlue;
            style.ParagraphFormat.PageBreakBefore = true;
            style.ParagraphFormat.SpaceAfter = 6;

            style = Doc.Styles["Heading2"];
            style.Font.Size = 12;
            style.Font.Bold = true;
            style.ParagraphFormat.PageBreakBefore = false;
            style.ParagraphFormat.SpaceBefore = 6;
            style.ParagraphFormat.SpaceAfter = 6;

            style = Doc.Styles["Heading3"];
            style.Font.Size = 10;
            style.Font.Bold = true;
            style.Font.Italic = true;
            style.ParagraphFormat.SpaceBefore = 6;
            style.ParagraphFormat.SpaceAfter = 3;

            style = Doc.Styles[StyleNames.Header];
            style.ParagraphFormat.AddTabStop("16cm", MigraDoc.DocumentObjectModel.TabAlignment.Right);

            style = Doc.Styles[StyleNames.Footer];
            style.ParagraphFormat.AddTabStop("8cm", MigraDoc.DocumentObjectModel.TabAlignment.Center);

            // Create a new style called TextBox based on style Normal
            style = Doc.Styles.AddStyle("TextBox", "Normal");
            style.ParagraphFormat.Alignment = ParagraphAlignment.Justify;
            style.ParagraphFormat.Borders.Width = 2.5;
            style.ParagraphFormat.Borders.Distance = "3pt";
            style.ParagraphFormat.Shading.Color = Colors.SkyBlue;

            // Create a new style called TOC based on style Normal
            style = Doc.Styles.AddStyle("TOC", "Normal");
            style.ParagraphFormat.AddTabStop("16cm", MigraDoc.DocumentObjectModel.TabAlignment.Right, TabLeader.Dots);
            style.ParagraphFormat.Font.Color = Colors.Blue;
        }

static void DefineContentSection(Document Doc)
{
Section section = Doc.AddSection();
section.pageSetup = Doc.DefaultPageSetup.Clone();
section.PageFormat = PageFormat.A4;
var width = section.Pagesetup.PageWidth;

section.PageSetup.LeftMargin = "2.5cm"
section.PageSetup.RightMargin = "2.5cm"
section.PageSetup.TopMargin = "8.0cm"
section.PageSetup.ButtomMargin = "5.0cm"

section.PageSetup.DifferentFirstpageHeaderFooter = true;
section.PageSetup.OddAndEvenPageHeaderFooter = true;
section.PageSetup.StartingNumber = 1;

Table table = new Table();
float sectionWidth = width - section.PageSetup.LeftMargin - section.PageSetup.RightMargin;
float colWidth = sectionWidth / 4;

table.Borders.Width = 0.75;

Column col = tabke.AddColumn();
col.Width = colWidth;
Column col = tabke.AddColumn();
col.Width = colWidth;
Column col = tabke.AddColumn();
col.Width = colWidth;
Column col = tabke.AddColumn();
col.Width = colWidth;

//Now filling with content

Row row = table.AddRow();
Cell cell = row.Cells[0];
cell.addParagraph("A cell 1.1");
Cell cell = row.Cells[1];
cell.addParagraph("A cell 1.2");

row = table.AddRow();
Cell cell = row.Cells[0];
cell.addParagraph("A cell 2.1");
Cell cell = row.Cells[1];
cell.addParagraph("A cell 2.2");
Cell cell = row.Cells[2];
cell.addParagraph("A cell 2.3");
Cell cell = row.Cells[3];
cell.addParagraph("A cell 2.4");

row = table.AddRow();
Cell cell = row.Cells[0];
cell.addParagraph("A cell 3.1");
Cell cell = row.Cells[1];
cell.addParagraph("A cell 3.2");
Cell cell = row.Cells[2];
cell.addParagraph("A cell 3.3");
Cell cell = row.Cells[3];
cell.addParagraph("A cell 3.4");

//I'm doing this eight times
.
.
.
//When the table is complete

section.Headers.FirstPage.Add(table);


//Now adding 100 lines of BodyText
for(int i = 0; i<99;i++)
{
section.AddParagraph("This is a test line.")
}


            Paragraph footerpar = new Paragraph();
            footerpar.AddTab();
            footerpar.AddPageField();
            section.Footers.FirstPage.Add(footerpar);

            HeaderFooter header = section.Headers.Primary;
            header = section.Headers.Primary;
            header.AddParagraph("\tOdd Page Header");

            header = section.Headers.EvenPage;
            header.AddParagraph("Even Page Header");


            // Create a paragraph with centered page number. See definition of style "Footer".
            Paragraph paragraph = new Paragraph();
            paragraph.AddTab();
            paragraph.AddPageField();

            // Add paragraph to footer for odd pages.
            section.Footers.Primary.Add(paragraph);
            // Add clone of paragraph to footer for odd pages. Cloning is necessary because an object must
            // not belong to more than one other object. If you forget cloning an exception is thrown.
            section.Footers.EvenPage.Add(paragraph.Clone());
}



I have not come to the point to add the smaller table for the other pages so the Even and Odd headers are used as a placeholder.

Can anyone give me a hint how I can solve the problem?

Thank you very much!


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 07, 2017 10:33 am 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3095
Location: Cologne, Germany
Hi!
OVS wrote:
I tried to use margins but they only will be good for the first page.
Set the margin for the second page. Start the first page with a big empty paragraph that reserves the extra space for the larger table on the first page. You can set SpaceAfter or SpaceBefore for that paragraph or set an exact height.
It's a hack, but it's fairly easy to do for the first-page header.

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 07, 2017 10:51 am 
Offline

Joined: Mon Nov 06, 2017 3:53 pm
Posts: 18
Hi, thank you for your reply.

Ok so, I'll set my margin for the second page.

I'll write my first page header.

I'll create a new paragraph

Code:
Paragraph Spacepar = new Paragraph();
Spacepar.Format.SpaceAfter = 120; //or SpaceBefore
section.Add(Spacepar)


This will work, but as you said it is a hack.

What did you mean by "or set an exact height."
I haven't fount this option in the paragraph format yet. Can you give me an example?

Thank you!

Edit:Found it out myself. Tried "2cm" and it works as expected.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 07, 2017 10:56 am 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3095
Location: Cologne, Germany
Look at "para.Format.LineSpacing" and "para.Format.LineSpacingRule".

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 10, 2017 7:08 am 
Offline

Joined: Mon Nov 06, 2017 3:53 pm
Posts: 18
Thank you again.

One more thing, I don't want to open an extra topic but I will do so if needed.

Regarding fonts and styles

As I mentioned in the first post I'm using your example code for 'Hello MigraDoc'.

In the methode DefineStyles we have

Code:
private void DefineStyles(Document Doc)
{
            Style style = Doc.Styles["Normal"];
            style.Font.Name = "Times new Roman";
 
            style = Doc.Styles["Heading1"];
            style.Font.Name = "Tahoma";
            style.Font.Size = 14;
            style.Font.Bold = true;
            style.Font.Color = Colors.DarkBlue;
            style.ParagraphFormat.PageBreakBefore = true;
            style.ParagraphFormat.SpaceAfter = 6;
.
.
.
}



Now I want to add a font w/ an different font (lets say Arial) and properties. And later use it by its given name (say "Title")

I altered the code like this

Code:
private void DefineStyles(Document Doc)
{
            Style style = Doc.Styles["Normal"];
            style.Font.Name = "Arial";
 
            style = Doc.Styles["Title"];
            style.Font.Size = 26;
            style.Font.Bold = true;
            style.Font.Color = Colors.DarkBlue;
            style.ParagraphFormat.PageBreakBefore = true;
            style.ParagraphFormat.SpaceAfter = 6;
.
.
.
}


However it seems like that pdfSharp only supports a set of nine (Heading1 - Heading9) styles, because if i use "Title" instead of "Heading1-9" I get an exception thrown saying it 'Object reference not set to an instance of an object' at line 'style.Font.Size = 26'

I would like to use more easily comprehensible names like 'Title', 'Bodytext' or 'TableText' than the vague 'Heading1-9'.

Can you also help me with that?

Thank you very much.


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 10, 2017 7:51 am 
Offline
PDFsharp Expert
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 909
Location: CCAA
Hi!
OVS wrote:
I would like to use more easily comprehensible names like 'Title', 'Bodytext' or 'TableText' than the vague 'Heading1-9'.
Styles that are not part of the standard set must be added.

From the sample:
Code:
  // Create a new style called Table based on style Normal
  style = this.document.Styles.AddStyle("Table", "Normal");
  style.Font.Name = "Verdana";
  style.Font.Name = "Times New Roman";
  style.Font.Size = 9;

You can use "Heading1" as the base of your new "Title" style if that suits.

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 10, 2017 8:01 am 
Offline

Joined: Mon Nov 06, 2017 3:53 pm
Posts: 18
Ah good to know:

I'm using this code now and as far as now it does the trick.

Code:
style = Doc.Styles.AddStyle("Title","Normal");
style.Font.Name = "Arial";
style.Font.Size = 9;
...


Out of curiosity why do you set the Font.Name twice? One time to Verdana and then to Times New Roman?

TH-Soft wrote:
Code:
  // Create a new style called Table based on style Normal
  style = this.document.Styles.AddStyle("Table", "Normal");
  style.Font.Name = "Verdana";
  style.Font.Name = "Times New Roman";
  style.Font.Size = 9;

You can use "Heading1" as the base of your new "Title" style if that suits.


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 10, 2017 8:04 am 
Offline
PDFsharp Expert
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 909
Location: CCAA
OVS wrote:
Out of curiosity why do you set the Font.Name twice? One time to Verdana and then to Times New Roman?
No point doing this. I just copied the lines from the site without reading them. :wink:

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 10, 2017 8:10 am 
Offline

Joined: Mon Nov 06, 2017 3:53 pm
Posts: 18
:mrgreen:

Fine. Thank you.

Great forum btw. I'll try to be more active if I'm more into pdfsharp


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 141 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group