Files
Better-Seewo/Better-EN5/Services/Conversion/EnbxWriter.cs
雾启工作室 65d61b44d9 feat: 管理器支持深浅主题切换,发布 exe
- 新增 LightTheme.xaml 浅色主题资源
- 标题栏添加主题切换按钮(☀️/🌙)
- Manager 支持深浅主题互换
- 发布 Manager.exe (292KB) 和 Installer.exe (171KB)
- 插件安装包 Better-Seewo.2.0.0.exe (11.6MB)
2026-06-28 12:43:17 +08:00

149 lines
5.9 KiB
C#

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<string>();
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<string> 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<XElement>();
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);
}
}