This project has moved. For the latest updates, please go here.

images in table in header

Aug 24, 2012 at 10:40 AM

Hello,

first of all, hats off for the DocX. 

 I'm having problems with inserting image into a table in header  (basicaly, making an invoice document).

Problematic code is below. Inserting very same image in same table only located outside header works just fine.

error I get is: "Object reference not set to an instance of an object."

 

thanks,
Bojan

 

private static DocX CreateDocument()        {           
//new document creation                 
DocX document = DocX.Create(@"c:\Document1.docx");

// Add Headers and Footers to this document.               
document.AddHeaders();                Header header_default = document.Headers.odd;             document.AddFooters();                Footer footer_default = document.Footers.odd;                 

// add logo               
Novacode.Image logoimage = document.AddImage(@"C:\LOGO.jpg");               
Picture logopicture = logoimage.CreatePicture();               
logopicture.Height = 100;               
logopicture.Width = 100;              

// Add layout header table                
Table layout_header_table = header_default.InsertTable(2, 2);                layout_header_table.Design = TableDesign.TableNormal;                layout_header_table.AutoFit = AutoFit.Window;

Table layout_document_table = document.InsertTable(2, 2);                layout_document_table.Design = TableDesign.TableNormal;                layout_document_table.AutoFit = AutoFit.Window;

Paragraph pheader = layout_header_table.Rows[0].Cells[0].Paragraphs[0];                            

 // inserting image into pheader in document_table works..                
//Paragraph pheader = layout_document_table.Rows[0].Cells[0].Paragraphs[0];

pheader.AppendPicture(logopicture);                 

return document;        }

Dec 12, 2012 at 11:09 AM

same thing with me ....

 

I don't know if there is any other way to insert picture into header or footer

 

thanks to rise this issue 

Developer
Dec 12, 2012 at 11:15 AM

Try this (more or less). It's an old code I used

 

                    #region Header
                    Image header;
                    if (rTyp.ToLower() == "Raport Miesieczny".ToLower()) {
                        Image header_miesieczny = documentWord.AddImage(Assembly.GetExecutingAssembly().GetManifestResourceStream("Share_Management.Resources.raport_miesieczny_header.jpg"));
                        header = header_miesieczny;
                    } else {
                        Image header_kwartalny = documentWord.AddImage(Assembly.GetExecutingAssembly().GetManifestResourceStream("Share_Management.Resources.raport_kwartalny_header.jpg"));
                        header = header_kwartalny;
                    }
                    Picture headPicture = header.CreatePicture();
                    headPicture.Height = 161;
                    headPicture.Width = 610;
                    documentWord.AddHeaders();
                    Header headerOdd = documentWord.Headers.odd;
                    Header headerFirst = documentWord.Headers.first;
                    Paragraph picture_header_odd = headerOdd.Paragraphs[0].AppendPicture(headPicture);
                    Paragraph picture_header_first = headerFirst.Paragraphs[0].AppendPicture(headPicture);
                    //picture_header_first.AppendPicture(headPicture);
                    //picture_header_odd.AppendPicture(headPicture);
                    #endregion Header

Apr 12, 2013 at 10:06 PM
This works for me
        Dim Logo As Novacode.Image = document.AddImage("D:\WebSites\mysite\Images\newlslogo.jpg")
        Dim BBLogo As Picture = Logo.CreatePicture()

        Dim header_first As Header = document.Headers.first
        header_first.InsertTable(1, 2)
        header_first.Tables(0).Alignment = Alignment.center
        header_first.Tables(0).AutoFit = AutoFit.Window
        header_first.Tables(0).Rows(0).Cells(0).Paragraphs(0).AppendPicture(BBLogo)
        header_first.Tables(0).Rows(0).Cells(0).VerticalAlignment = VerticalAlignment.Top
        header_first.Tables(0).Rows(0).Cells(1).VerticalAlignment = VerticalAlignment.Center
        header_first.Tables(0).Rows(0).Cells(1).Paragraphs(0).Alignment = Alignment.right
Jun 23, 2013 at 6:58 AM
I meet the issue ,how can I insert picture into tablecell,thanks very much
Jul 31, 2013 at 4:03 PM
Invoice Template example not show header logo image please help how to solve this issue
Aug 9, 2013 at 2:18 PM
Hi All!

I found the NullReferenceException bug and I have a solution for it!

I use the latest build to get the source code and modify it. I take a look at the source code and I found the NullReferenceException's source.
If you create headers, insert a table into it and then try to append an image to the first paragraph you will get the exception, because the Paragraph's mainPart filed is null. After that I go to the InsertTable method, and I simply added the Document's mainPart field, to the new table, but the in the docx file the image was just an error message like this: "This image can not be displayed right now".
I dig in the code and I noticed that, the header does not contains InsertTable method and just used, the base (Container class) InsertTable method. I take a look at the Document class InsertTable method which is working perfectly, copied it to the Header class and it WORKS!!

The solution in a few step's:
  1. Download the latest release to get the source code
  2. Add it to your project (enough only the DocX project)
  3. In your project set the DocX reference to the DocX project (not the dll!)
  4. Open the "Header.cs" and the "DocX.cs"
  5. Copy the InsertTable methods from the "DocX.cs" and paste into the "Header.cs"
  6. Build the whole solution
It works for me and I really hope this solution will work to you :)

Happy coding,
Adam
Developer
Aug 23, 2013 at 10:02 AM
Thank Adam aka Slipy. I've tested your solution and expanded it into footers as well. I've also added an example into Examples source codes. Thank you once again.

@hnalawade
What problem do you have? Use AppendPicture in Headers and Footers and it will work. InsertPicture gives and empty image.
Apr 23, 2014 at 10:17 PM
Edited Apr 23, 2014 at 10:19 PM
Is it possible this same error is also when adding Tables using InsertTableAfterSelf ?
I do not add this table in the Header, just in the main document.

I use this to copy a table (in a paragraph of main docx document) after itself:
var parProdTable = docx.Paragraphs.FirstOrDefault(o => o.Text.Contains("searchtext"));

Table tProduct = parProdTable.FollowingTable;
Table tPnew = tProduct.InsertTableAfterSelf(tProduct);
Then when I try to add a Picture, in a paragraph of a tPnew cell, the mainPart is also null.

Novacode.Image img = docx.AddImage(@img_path);
Picture pic1 = img.CreatePicture();

// p is first paragraph of a cell of tPnew
p.AppendPicture(pic1);


From Paragraph.cs (docx latest source code, downloaded today):
public Paragraph AppendPicture(Picture p)
{
    // Convert the path of this mainPart to its equilivant rels file path.
    string path = mainPart.Uri.OriginalString.Replace("/word/", "");
    Uri rels_path = new Uri("/word/_rels/" + path + ".rels", UriKind.Relative);

    // Check to see if the rels file exists and create it if not.
    if (!Document.package.PartExists(rels_path))
        HelperFunctions.CreateRelsPackagePart(Document, rels_path);
    
    ...
}
Copying the table works, I see multiple table copies in my document.
When I add the picture to the main document, the picture is shown correctly.
Apr 23, 2014 at 10:31 PM
Investigated this a little more and found out that the parProdTable does contain a mainpart object.
Then when I use 'FollowingTable' to get the first table for parProdTable, then mainpart is null.
So the FollowingTable method destroys the mainpart object?
Apr 23, 2014 at 10:45 PM
Got it working by doing this:
  • The FollowingTable objects are set in 'Container.cs'
public virtual ReadOnlyCollection<Paragraph> Paragraphs
{
    get
    {
        List<Paragraph> paragraphs = GetParagraphs();

        foreach (var p in paragraphs)
        {
            if ((p.Xml.ElementsAfterSelf().FirstOrDefault() != null) && (p.Xml.ElementsAfterSelf().First().Name.Equals(DocX.w + "tbl")))
                p.FollowingTable = new Table(this.Document, p.Xml.ElementsAfterSelf().First());

            p.ParentContainer = GetParentFromXmlName(p.Xml.Ancestors().First().Name.LocalName);

            if (p.IsListItem)
            {
                GetListItemType(p);
            }
        }

        return paragraphs.AsReadOnly();
    }
}
  • The line 'p.FollowingTable = new Table (...)' calls a Table constructor from Table.cs
internal Table(DocX document, XElement xml)
            : base(document, xml)
{
    autofit = AutoFit.ColumnWidth;
    this.Xml = xml;

    XElement properties = xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));

    XElement style = properties.Element(XName.Get("tblStyle", DocX.w.NamespaceName));
    if (style != null)
    {
    ...
    }
}
  • In this constructor, the mainpart is not copied from the Document object, so I added it. Now the constructor looks like:
internal Table(DocX document, XElement xml)
            : base(document, xml)
{
    autofit = AutoFit.ColumnWidth;
    this.Xml = xml;

    this.mainPart = document.mainPart;

    XElement properties = xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));

    XElement style = properties.Element(XName.Get("tblStyle", DocX.w.NamespaceName));
    if (style != null)
    {
    ...
    }
}
Now the mainpart is not null, and I can add Pictures in my table.
Apr 25, 2014 at 12:40 PM
@Devs: Do you want me to create a patch for this? I assume it takes less time for you to just add this one line of code to Table.cs instead of processing my patch? Thanks and keep up the good work! :)
Developer
Apr 28, 2014 at 9:04 PM
Nah, it's fine. Thank you. Added to source code. You can verify if everything is fine :-)
Marked as answer by MadBoy on 4/28/2014 at 2:05 PM