Convert docx to HTML with multiple images

I’m working on an application which converts docx templates into HTML which will be emailed.
Everything is working with one image in the template.
I received the request to have a multiple images (Facebook link and Twitter link). Is there a way to have multiple images in a document?
Here is my code:

public static byte[] ConvertToHtml(byte[] inBuffer, string imageLocation, byte[] licenseBuffer)
{
    MemoryStream inStream = new MemoryStream(inBuffer);
    if (inStream == null)
        throw new ApplicationException("ConvertToHtml() MemoryStream is null");

    License license = new License();
    license.SetLicense(new MemoryStream(licenseBuffer));

    Document doc = new Document(inStream);
    // Save the document to stream.

    MemoryStream outStream = new MemoryStream();

    HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.Html);
    options.ImagesFolderAlias = imageLocation;
    options.ImageSavingCallback = new HandleImagesSaving();

    doc.Save(outStream, options);
    outStream.Seek(0, System.IO.SeekOrigin.Begin);

    // convert stream to byte array
    byte[] docBytes = outStream.ToArray();

    return docBytes;
}

private class HandleImagesSaving : IImageSavingCallback
{
    void IImageSavingCallback.ImageSaving(ImageSavingArgs e)
    {
        e.ImageStream = new MemoryStream();
        e.KeepImageStreamOpen = false;
    }
}

Hi
Jaime,

Thanks for your inquiry. What I understand, you’re trying to get byte[] against each image that is found in DOCX upon converting to HTML. In this case, you can take image byte arrays from inside the IImageSavingCallback handler. In case, I misunderstood, could you please explain your problem in more detail?

Best Regards,

Hi Awais,
Thank you for your quick response.
Currently I have the document with one logo image. Everything is functioning correctly. I’m setting the image file name in the call back function.
Here is the code:

public static byte[] ConvertToHtml(byte[] inBuffer, string imageLocation, string imageName, byte[] licenseBuffer)
{
    MemoryStream inStream = new MemoryStream(inBuffer);
    if (inStream == null)
        throw new ApplicationException("ConvertToHtml() MemoryStream is null");

    License license = new License();
    license.SetLicense(new MemoryStream(licenseBuffer));

    Document doc = new Document(inStream);

    // Save the document to stream.

    MemoryStream outStream = new MemoryStream();

    HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.Html);
    options.ImagesFolderAlias = imageLocation;
    options.ImageSavingCallback = new HandleImageSaving(imageName);

    doc.Save(outStream, options);
    outStream.Seek(0, System.IO.SeekOrigin.Begin);

    // convert stream to byte array

    byte[] docBytes = outStream.ToArray();

    return docBytes;
}

private class HandleImageSaving : IImageSavingCallback
{
    private string _imageName;

    public HandleImageSaving(string imageName)
    {
        _imageName = imageName;
    }

    void IImageSavingCallback.ImageSaving(ImageSavingArgs e)
    {
        // Change any images in the document being exported with the extension of "jpeg" to "jpg".

        if (Path.GetExtension(e.ImageFileName).Equals(".jpeg"))
            e.ImageFileName = Path.ChangeExtension(e.ImageFileName, ".jpg");

        MemoryStream imgStream = new MemoryStream();
        e.ImageStream = imgStream;
        e.KeepImageStreamOpen = false;
        e.ImageFileName = _imageName;

    }
}

Now I need to add 2 more images with links. How can I do this without providing the name for each image? Please show me a sample of this.

Hi Jaime,

Thanks for your inquiry. I think, I can offer you a much simpler way to achieve what you’re looking for. Please see the following code snippet:

Document doc = new Document(inStream);
MemoryStream outStream = new MemoryStream();

HtmlSaveOptions options = new HtmlSaveOptions(SaveFormat.Html);
options.ImagesFolderAlias = imageLocation;
// When this property is set to true image data is exported directly on the img elements and separate files are not created. 
options.ExportImagesAsBase64 = true;

doc.Save(outStream, options);

byte[] docBytes = outStream.ToArray();

I hope, this will help.

Best Regards,

Hi Awais,
Thank you for your response.
It is working great on the iPhone and the file opens in multiple browsers using the html file. The error occurs in outlook and other email applications when the image is embedded in the html code. For an unknown reason, I cannot see the image through an email application. Are there any other solutions available?
Thank you

Hi
Jaime,

Thanks for your inquiry. Perhaps, in this case, you should just save your documents to MHTML format. You can also use Aspose.Words and Aspose.Network together to generate and send email messages with rich content. For example, you can load a predefined DOC, OOXML or RTF document into Aspose.Words, fill it with data, save as MHTML and then email using Aspose.Network. Please read the following article for more details:
https://docs.aspose.com/words/net/convert-a-document-to-mhtml-and-send-it-by-email/

I hope, this will help.

Best Regards,

Hi Awais,
Thank you for your response.
I cannot identify any API for Aspose.Network. Did you mean Aspose.Email?
I downloaded and installed Aspose.Email.
I loaded my document into Aspose.Word and saved it as a MHTML file. It is working perfectly for Outlook and Gmail, but it’s not functioning properly on Apple devices (Mac, iPad or iPhone).
Below are the solutions that you provided:
1.) options.ExportImagesAsBase64 – working correctly on Apple devices, but not operating properly in Outlook.
2.) MHTML – working in Outlook but not on Apple devices.

Please advise before I purchase Aspose.Email, because I am still not obtaining the results I require.
Thank you

Hi Jaime,

Thanks for your inquiry. Aspose.Network component is actually renamed to Aspose.Email; I appologise for this confusion. Secondly, it would be great if you could create some screen shots which shows your problems with outlook and Apple devices. We will investigate the issues further and provide you more information.

Best Regards,

Hi Awais,
Here is the screen shots.
Best Regards,
Jaime

Hi Jaime,

Thanks for your inquiry.

The reason for the issues you are having is because:

  • Outlook does not support base64 embedded images.
  • Safari does not support MHTML documents.

Whereas the suggestions given previously by Awais are correct, since you are looking for support on both systems neither suggestion will work for both.

Could you please clarify what you are doing with the image streams and the HTML after you have finished with them? Do you save them to disk?

Please test simply saving the images in the same directory as the HTML file. If you copy all files to the iPhone then it should open fine. Outlook should also be able to open the output correctly. Please see the code below:

HtmlSaveOptions

htmlOptions = new HtmlSaveOptions();
htmlOptions.ImagesFolder = @"C:\Document Out\";
htmlOptions.ImagesFolderAlias = string.Empty;
doc.Save(@"C:\Document Out\Document Out.html", htmlOptions);

Thanks,

Hi Adam,
Thank you for your response.
Here are my steps to generate the HTML email.
I have the templates with images (linked to one of our web server) saved in Microsoft Word (.docx format). I’m parsing the template and replacing the variables with data. Then I calling Aspose API to convert to HTML format and then send email.
When I saved on disk locally it working but I need make this working with stream.
Nothing is getting saved to a disk. In my third response to Awais you can see the code I’m using for one image, one image working perfect. Now I need do the same thing with multiple images.
This email will be generated with different contents for thousand users when reservations are secured and require a confirmation and I cannot continue to save each one to the hard drive.
We purchased Aspose.Word to accomplish this task and this does not appear to be a total solution. I need assistance in solving this issue ASAP!
Thanks,
Jaime

Hi Jaime,

Thanks for the additional information.

We will be sure to get your application working, please bear with us while we find the particular solution for your situation.

I’m afraid I still need some further clarification:

  • Do you do anything with the image streams after the callback is finished? i.e are they uploaded to your site?
  • What does value the imageLocation variable contain?

It would be good if you could clarify exactly how you want images referenced in the HTML Do you want to pass the images with the HTML or do you want them to point to a URL address where the images have been uploaded to ?

Thanks,