EvotecIT / OfficeIMO

Fast and easy to use cross-platform .NET library that creates or modifies Microsoft Word (DocX) and later also Excel (XLSX) files without installing any software. Library is based on Open XML SDK
MIT License
263 stars 47 forks source link

[Bug]Do Table Cells support adding images? #174

Closed tmheath closed 6 months ago

tmheath commented 7 months ago

I just implemented image frames as a 2x1 table with the top containing an image and the bottom containing some text as a caption. The method works on a blank document for appending an image to it and does not work for this purpose. I can supply examples for what I mean.

Code can be found at https://sourceforge.net/p/f-docx/code/ci/master/tree/Program.fs The test script throws a null reference exception in the final call to save. https://sourceforge.net/p/f-docx/code/ci/master/tree/bin/Debug/net7.0/publish/test.fsx

Each file is short, if this feature is currently supported then do you know what I need to be doing instead?

Thanks

tmheath commented 7 months ago

image Seen above the documentation implies the result is going to be a paragraph. Seen below there is a failure since the parent is null but the method used to create the parent does not return nullable. image The code in question is below. ((addParagraph "").AddImage (image.path, image.width, image.height, wrap)).AddParagraphAfterSelf() |> ignore I got this from adding the call to addparagraphafterself to try checking if it was due to the requirement to end a cell with a paragraph. This tells me that AddImage is returning null, I can't say more than this as I don't know the codebase.

tmheath commented 7 months ago
    public WordParagraph AddImage(string filePathImage, double? width = null, double? height = null, WrapTextImage wrapImageText = WrapTextImage.InLineWithText, string description = "") {
        var wordImage = new WordImage(_document, this, filePathImage, width, height, wrapImageText, description);
        // Why was this change made?
        //var wordImage = new WordImage(_document, filePathImage, width, height);
        var paragraph = new WordParagraph(_document);
        VerifyRun();
        _run.Append(wordImage._Image);
        return paragraph;
tmheath commented 7 months ago

Looked around some, thinking I'm going to be looking around the Table Cell code in the morning.

tmheath commented 7 months ago

@PrzemyslawKlys

I believe that I found the problem. WordTableCell creates a brand new WordParagraph via call to the default constructor with no arguments using new. This causes the paragraph not to have it's own reference to _document, the field will be left null, and so when addImage is called on this paragraph, there is an error because _wordimage is passed the null reference to the document from the paragraph so the image resource cannot be added to the root of the document. WordParagraph public methods WordParagraph constructor definition WordTableCell

Should I submit a PR adding an optional argument for the _document reference to the addImage method on WordParagraph?

tmheath commented 7 months ago

The alternative short term fix for adding an image into a table looks like the user needs to explicitly create a WordParagraph from the document or directly and then add this paragraph into the table cell.

tmheath commented 7 months ago

Just looked over the existing PR for improving the table class and this fix is not yet present there, maybe better to fix there idk.

PrzemyslawKlys commented 7 months ago

You can always try fixing it, I will need to look at code to be able to tell whether that's the simplest way to fix it. for me if you have optional parameter that requires you to "fix" this or it throws an error - it's not good design. I would prefer something automatic, so when user does AddImage it just works without thinking on "paragraphs", but maybe there's no other way. I'll take a look when I get some time, but if you want you can always play with it.