using System; using System.Collections.Generic; using System.IO; using System.IO.Packaging; using System.Linq; using System.Xml.Linq; namespace BetterEN5.Services.Conversion; public class EnbxWriter { private static readonly XNamespace En = "http://schemas.seewo.com/easinote/2016/document"; private static readonly XNamespace Dc = "http://purl.org/dc/elements/1.1/"; public void Write(DocumentModel doc, string outputPath) { if (File.Exists(outputPath)) File.Delete(outputPath); using var package = Package.Open(outputPath, FileMode.Create); var docPart = package.CreatePart( PackUriHelper.CreatePartUri(new Uri("/document.xml", UriKind.Relative)), "application/xml"); var slideTargets = new List(); int slideIndex = 0; foreach (var slide in doc.Slides) { slideIndex++; var slideName = $"slides/slide{slideIndex}.xml"; slideTargets.Add(slideName); var slidePart = package.CreatePart( PackUriHelper.CreatePartUri(new Uri($"/{slideName}", UriKind.Relative)), "application/xml"); int imgIdx = 0; foreach (var elem in slide.Elements) { if (elem is ImageElement img && img.Data != null && img.Data.Length > 0) { imgIdx++; var ext = Path.GetExtension(img.FileName); if (string.IsNullOrEmpty(ext)) ext = ".png"; var mediaName = $"media/{Guid.NewGuid():N}{ext}"; var imagePart = package.CreatePart( PackUriHelper.CreatePartUri(new Uri($"/{mediaName}", UriKind.Relative)), img.ContentType); using (var s = imagePart.GetStream()) s.Write(img.Data, 0, img.Data.Length); slidePart.CreateRelationship( PackUriHelper.CreatePartUri(new Uri($"/{mediaName}", UriKind.Relative)), TargetMode.Internal, "http://schemas.seewo.com/easinote/relationships/image", $"r{imgIdx}"); img.FileName = mediaName; } } WriteSlideXml(slidePart, slide); docPart.CreateRelationship( PackUriHelper.CreatePartUri(new Uri($"/{slideName}", UriKind.Relative)), TargetMode.Internal, "http://schemas.seewo.com/easinote/relationships/slide", $"r{slideIndex}"); } WriteDocumentXml(docPart, doc, slideTargets); package.CreateRelationship( PackUriHelper.CreatePartUri(new Uri("/document.xml", UriKind.Relative)), TargetMode.Internal, "http://schemas.seewo.com/easinote/relationships/document", "rId1"); } private void WriteDocumentXml(PackagePart docPart, DocumentModel doc, List slideTargets) { var docXml = new XDocument( new XElement(En + "Document", new XAttribute(XNamespace.Xmlns + "en", En.NamespaceName), new XAttribute(XNamespace.Xmlns + "dc", Dc.NamespaceName), new XElement(En + "Properties", new XElement(En + "Title", doc.Title), new XElement(En + "Author", doc.Author), new XElement(En + "Created", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss")), new XElement(En + "Application", "Better-Seewo"), new XElement(En + "Version", "5.2.4.9855"), new XElement(En + "SlideWidth", doc.SlideWidth), new XElement(En + "SlideHeight", doc.SlideHeight)), new XElement(En + "Slides", slideTargets.Select((t, i) => new XElement(En + "Slide", new XAttribute("RId", $"r{i + 1}"), new XAttribute("Source", t)))))); using var stream = docPart.GetStream(FileMode.Create); docXml.Save(stream); } private void WriteSlideXml(PackagePart slidePart, SlideModel slide) { var elems = new List(); int imgIdx = 0; foreach (var e in slide.Elements) { switch (e) { case TextElement t: elems.Add(new XElement(En + "TextElement", new XAttribute("X", t.X), new XAttribute("Y", t.Y), new XAttribute("Width", t.Width), new XAttribute("Height", t.Height), new XAttribute("FontSize", t.FontSize), new XAttribute("IsBold", t.IsBold), new XAttribute("FontName", t.FontName), new XAttribute("FontColor", t.FontColor), new XElement(En + "Text", t.Text))); break; case ImageElement img: imgIdx++; elems.Add(new XElement(En + "ImageElement", new XAttribute("X", img.X), new XAttribute("Y", img.Y), new XAttribute("Width", img.Width), new XAttribute("Height", img.Height), new XAttribute("Source", img.FileName), new XAttribute("RId", $"r{imgIdx}"))); break; } } var slideXml = new XDocument( new XElement(En + "Slide", new XAttribute(XNamespace.Xmlns + "en", En.NamespaceName), new XAttribute("Width", slide.Width), new XAttribute("Height", slide.Height), new XElement(En + "Elements", elems))); using var stream = slidePart.GetStream(FileMode.Create); slideXml.Save(stream); } }