Problem Exporting from C# to NodeXL using OpenXML

Dec 10, 2009 at 2:54 PM

When trying to populate a NodeXL Template from code using OpenXML, only the first row got processed, as the rest of rows formatting were not considered by NodeXL. How do I fix it? This would be very useful in case you want to create a chart from your database!

For inserting row, I use:
theRow = new Row();
theRow.RowIndex = rowNumber;


Dec 10, 2009 at 4:36 PM

I'm not sure I understand what you need to do.  Are you writing C# code that creates a workbook from the NodeXL template and then populates the workbook's Edges worksheet?  If so, I suspect that appending rows to the worksheet isn't going to work.  (I haven't actually tried it myself.)  Instead, you need to access and populate the Edges table on the Edges worksheet.  Tables are known as ListObjects in the Excel object model, and you can access the Edges table with the following code:

ListObject edgesTable = worksheet.ListObjects["Edges"];

Once you get the Edges table, you can add rows to it with this:


But note that there is an alternative way to import custom data into NodeXL that completely bypasses the Excel workbook and its object model and instead requires only that you specify your graph contents as GraphML, a dialect of XML.  See "For Programmers: About NodeXL Plug-Ins" at

-- Tony

Dec 10, 2009 at 5:29 PM

On second reading: If you are attempting to populate a NodeXL workbook by manipulating its underlying OpenXML, that seems awfully indirect, fragile, and difficult to me.  I would either use the Excel object model to create a workbook from the NodeXL template and then populate the workbook, or create a NodeXL plug-in.  The plug-in is the easiest and most robust solution, in my opinion.

-- Tony

Dec 13, 2009 at 5:42 AM

Thanks for your response, Tony.

I'm not using Excel Object Model nor editing the XML files of OpenXML. I am using OpenXML SDK 2.0, which provides an easy way and API to build / access Excel documents. You can access data from Worksheet using the SheetData object. In this environment I didn't find the ListObject nor the "Table" within the worksheet.

        static WorksheetPart GetWorkSheetPart(WorkbookPart workbookPart, string sheetName)
            //Get the relationship id of the sheetname
            string relId = workbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name.Value.Equals(sheetName)).First().Id;
            return (WorksheetPart)workbookPart.GetPartById(relId);

WorkbookPart workbookPart = myWorkbook.WorkbookPart;
WorksheetPart EdgesWorksheetPart = GetWorkSheetPart(workbookPart, "Edges" );
Table t = EdgesWorksheetPart.Worksheet.GetFirstChild<Table>();  // This gives me null.
SheetData EdgesSheetData = EdgesWorksheetPart.Worksheet.GetFirstChild<SheetData>();  // This gives me the actual data

The advantage of populating the worksheet directly instead of making the plug-in (i.e. generating the GraphML) is that my application would automatically open an Excel document with all information already there, instead of requiring the user to click on "NodeXL" -> "Import" -> "From GraphML file" / Custom data source.


Dec 13, 2009 at 6:47 PM
Edited Jun 2, 2010 at 6:24 PM

I see.  But my previous comments still hold: I think that building the NodeXL workbook via the OpenXML SDK is indirect, fragile, and too difficult.  In fact, unless you have detailed knowledge of the required structure of the NodeXL workbook, it will be an impossible task.  For example, some worksheets are required, while some aren't.  Some tables within the worksheets are required, but some aren't.  And some columns within the tables are required, but some aren't.  And do you know how to embed references to the NodeXL assemblies within your newly created workbook?  If you don't do that, you won't see a NodeXL graph pane or ribbon tab when you open the workbook.  (It's done via a set of custom properties.)

Instead, I would use the Excel object model to create a workbook from the NodeXL template (Application.Workbooks.Add("NodeXLGraph.xltx"), and then populate the workbook via the object model.  You'll want to do it using table names ("Edges") and table column names ("Vertex 1", "Vertex 2"), as opposed to direct addressing ("A:B").  That way you will be reasonably immune from broken references when a column gets moved in a future release.

In short, the Excel object model is the way to go in your case.  OpenXML will only give you heartache.

-- Tony

Dec 15, 2009 at 7:53 AM

In fact I was always talking about having a NodeXL Template ready and working on top of it (not creating it from scratch). So, if we are talking Excel object model and having the GraphML ready, is there a way of Excel Automation to click on "NodeXL" -> "Import" -> "From GraphML file" automatically? I ask because the regular Excel automation (or Macros) handle regular Excel functions, and NodeXL is a plug-in.

If I can do so, I stay with the robustness and ease of importing GraphML files to the template and still have it automated! :).

Many thanks!


Dec 15, 2009 at 4:32 PM
Edited Dec 15, 2009 at 4:33 PM

You might be able to do it via Application.CommandBars:

But even if you get that to work, it will only bring up a dialog box for selecting a GraphML file; it won't be entirely automatic.

-- Tony