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

Code Updates You May Consider

Sep 2, 2011 at 10:18 PM

I've incorporated the source code into our project and made a couple of changes today.

You may want to incorporate them into your base code. Also, since you know the code better than I, I'd be interested if you see a better way to approach anything I've done.

Change 1: Test for null in AddImagePart. I had a case where this code was producing a null reference exception because d.Inline was null.

private Drawing AddImagePart(Uri imageUrl, String imageSource, String alt, Size preferredSize)
{
	if (imageObjId == UInt32.MinValue)
	{
		// In order to add images in the document, we need to asisgn an unique id
		// to each Drawing object. So we'll loop through all of the existing <wp:docPr> elements
		// to find the largest Id, then increment it for each new image.

		drawingObjId = 1; // 1 is the minimum ID set by MS Office.
		imageObjId = 1;
		foreach (var d in mainPart.Document.Body.Descendants<Drawing>())
		{
			// JBW 9/2/2011
			// Had case where d.Inline was null
			if (d.Inline != null)
			{
				if (d.Inline.DocProperties.Id > drawingObjId) drawingObjId = d.Inline.DocProperties.Id;

				var nvPr = d.Inline.Graphic.GraphicData.GetFirstChild<pic.NonVisualPictureProperties>();
				if (nvPr != null && nvPr.NonVisualDrawingProperties.Id > imageObjId)
					imageObjId = nvPr.NonVisualDrawingProperties.Id;
			}
		}
		if (drawingObjId > 1) drawingObjId++;
		if (imageObjId > 1) imageObjId++;
	}
}

Change 2: Discard empty table rows. Word will refuse to open a document that has a table row with no cells.

private void ProcessClosingTableRow(HtmlEnumerator en)
{
	if (!tables.HasContext) return;
	TableRow row = tables.CurrentTable.GetLastChild<TableRow>();

	// JBW 9/2/2011
	// Word will not open documents with empty rows
	if (row == null) return;
	if (row.GetFirstChild<TableCell>() == null)
	{
		row.Remove();
		return;
	}

    // Add empty columns to fill rowspan
    if (tables.RowSpan.Count > 0)
    {
        int rowIndex = tables.CellPosition.Y;

        for (int i = 0; i < tables.RowSpan.Count; i++)
        {
            Point position = tables.RowSpan.Keys[i];
            if (position.Y == rowIndex) continue;

            row.InsertAt<TableCell>(new TableCell(new TableCellProperties(
                                        new VerticalMerge()),
                                    new Paragraph()),
                position.X);

            int span = tables.RowSpan[position];
            if (span == 1) { tables.RowSpan.RemoveAt(i); i--; }
            else tables.RowSpan[position] = span - 1;
        }
    }

    htmlStyles.Tables.EndTagForParagraph("<tr>");
    htmlStyles.Runs.EndTag("<tr>");
}