Skip to content

Commit cd403cb

Browse files
authored
Merge pull request #10 from Codeuctivity/CustomImageHandler
ExportImageHandler implemented
2 parents fe3f9fd + c4ba5d4 commit cd403cb

File tree

3 files changed

+87
-5
lines changed

3 files changed

+87
-5
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using OpenXmlPowerTools;
2+
using OpenXmlPowerTools.OpenXMLWordprocessingMLToHtmlConverter;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
using System.Xml.Linq;
7+
8+
namespace Codeuctivity.OpenXmlToHtml
9+
{
10+
public class ExportImageHandler : IImageHandler
11+
{
12+
public IDictionary<string, byte[]> Images { get; }
13+
14+
public ExportImageHandler(IDictionary<string, byte[]> images)
15+
{
16+
Images = images;
17+
}
18+
19+
public XElement TransformImage(ImageInfo imageInfo)
20+
{
21+
var cid = Guid.NewGuid().ToString();
22+
using var memoryStream = new MemoryStream();
23+
imageInfo.Bitmap.Save(memoryStream, imageInfo.Bitmap.RawFormat);
24+
25+
Images.Add(cid, memoryStream.ToArray());
26+
27+
var cidReference = $"cid: {cid}";
28+
29+
return new XElement(Xhtml.img, new XAttribute(NoNamespace.src, cidReference), imageInfo.ImgStyleAttribute, imageInfo.AltText != null ? new XAttribute(NoNamespace.alt, imageInfo.AltText) : null);
30+
}
31+
}
32+
}

OpenXmlToHtml/OpenXmlToHtml.cs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using OpenXmlPowerTools;
33
using OpenXmlPowerTools.OpenXMLWordprocessingMLToHtmlConverter;
44
using System;
5+
using System.Collections.Generic;
56
using System.IO;
67
using System.Linq;
78
using System.Threading.Tasks;
@@ -55,10 +56,27 @@ public static Task<Stream> ConvertToHtmlAsync(Stream sourceOpenXml, string fallb
5556
throw new ArgumentNullException(nameof(sourceOpenXml));
5657
}
5758

58-
return ConvertToHtmlInternalAsync(sourceOpenXml, fallbackPageTitle);
59+
return ConvertToHtmlInternalAsync(sourceOpenXml, fallbackPageTitle, new ImageHandler());
5960
}
6061

61-
private static async Task<Stream> ConvertToHtmlInternalAsync(Stream sourceOpenXml, string fallbackPageTitle)
62+
/// <summary>
63+
/// Converts docx to html
64+
/// </summary>
65+
/// <param name="sourceOpenXml"></param>
66+
/// <param name="fallbackPageTitle"></param>
67+
/// <param name="images"></param>
68+
/// <returns>selfContainedHtml</returns>
69+
public static Task<Stream> ConvertToHtmlAsync(Stream sourceOpenXml, string fallbackPageTitle, IDictionary<string, byte[]> images)
70+
{
71+
if (sourceOpenXml == null)
72+
{
73+
throw new ArgumentNullException(nameof(sourceOpenXml));
74+
}
75+
76+
return ConvertToHtmlInternalAsync(sourceOpenXml, fallbackPageTitle, new ExportImageHandler(images));
77+
}
78+
79+
private static async Task<Stream> ConvertToHtmlInternalAsync(Stream sourceOpenXml, string fallbackPageTitle, IImageHandler imageHandler)
6280
{
6381
using var memoryStream = new MemoryStream();
6482
await sourceOpenXml.CopyToAsync(memoryStream).ConfigureAwait(false);
@@ -69,17 +87,17 @@ private static async Task<Stream> ConvertToHtmlInternalAsync(Stream sourceOpenXm
6987
var computedPageTitle = coreFilePropertiesPart?.GetXDocument().Descendants(DC.title).FirstOrDefault();
7088
var pageTitle = string.IsNullOrEmpty(computedPageTitle?.Value) ? fallbackPageTitle : computedPageTitle!.Value;
7189

72-
var htmlElement = WmlToHtmlConverter.ConvertToHtml(wordProcessingDocument, CreateHtmlConverterSettings(pageTitle));
90+
var htmlElement = WmlToHtmlConverter.ConvertToHtml(wordProcessingDocument, CreateHtmlConverterSettings(pageTitle, imageHandler));
7391

7492
var memoryStreamHtml = new MemoryStream();
7593
htmlElement.Save(memoryStreamHtml);
7694
memoryStreamHtml.Position = 0;
7795
return memoryStreamHtml;
7896
}
7997

80-
private static WmlToHtmlConverterSettings CreateHtmlConverterSettings(string pageTitle)
98+
private static WmlToHtmlConverterSettings CreateHtmlConverterSettings(string pageTitle, IImageHandler imageHandler)
8199
{
82-
var settings = new WmlToHtmlConverterSettings(pageTitle, new ImageHandler(), new TextSymbolToUnicodeHandler(), new SymbolHandler(), new PageBreakHandler(new BreakHandler()), true, string.Empty, "@page { size: A4 } body { margin: 1cm auto; max-width: 20cm; padding: 0; }", "Codeuctivity-");
100+
var settings = new WmlToHtmlConverterSettings(pageTitle, imageHandler, new TextSymbolToUnicodeHandler(), new SymbolHandler(), new PageBreakHandler(new BreakHandler()), true, string.Empty, "@page { size: A4 } body { margin: 1cm auto; max-width: 20cm; padding: 0; }", "Codeuctivity-");
83101

84102
return settings;
85103
}

OpenXmlToHtmlTests/OpenXmlToHtmlTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
using Codeuctivity.OpenXmlToHtml;
22
using Codeuctivity.PuppeteerSharp;
33
using PdfSharp.Pdf.IO;
4+
using System.Collections.Generic;
5+
using System.Drawing;
46
using System.IO;
7+
using System.Linq;
58
using System.Threading.Tasks;
69
using Xunit;
710

@@ -29,6 +32,35 @@ public async Task ShouldConvertDocumentIntegrativeWithKnownAberrancyTest(string
2932
await DocumentAsserter.AssertRenderedHtmlIsEqual(actualHtmlFilePath, expectedHtmlFilePath, allowedPixelErrorCount);
3033
}
3134

35+
[Theory]
36+
[InlineData("Images.docx")]
37+
public async Task ShouldConvertDocumentAndExportImagesIntegrativeTest(string testFileName)
38+
{
39+
var sourceOpenXmlFilePath = $"../../../TestInput/{testFileName}";
40+
var actualHtmlFilePath = Path.Combine(Path.GetTempPath(), $"Actual{testFileName}.html");
41+
42+
if (File.Exists(actualHtmlFilePath))
43+
{
44+
File.Delete(actualHtmlFilePath);
45+
}
46+
47+
using var sourceIpenXml = new FileStream(sourceOpenXmlFilePath, FileMode.Open, FileAccess.Read);
48+
var exportedImages = new Dictionary<string, byte[]>();
49+
50+
await OpenXmlToHtml.ConvertToHtmlAsync(sourceIpenXml, "fallbackTitle", exportedImages);
51+
52+
Assert.Equal(2, exportedImages.Count);
53+
54+
Assert.True(IsValidBitmap(exportedImages.First().Value));
55+
Assert.True(IsValidBitmap(exportedImages.Last().Value));
56+
}
57+
58+
private bool IsValidBitmap(byte[] blob)
59+
{
60+
var bitmap = new Bitmap(new MemoryStream(blob));
61+
return bitmap.Width > 1 && bitmap.Height > 1;
62+
}
63+
3264
[Fact]
3365
public async Task ShouldConvertDocumentIntegrativeWithToExpectedPageQuantityTest()
3466
{

0 commit comments

Comments
 (0)