Ods: Add settings.xml

This commit is contained in:
2023-11-13 19:22:21 +01:00
parent 3ee7a6e75e
commit 8509f04d4d

View File

@ -1,4 +1,5 @@
using Elwig.Models.Dtos;
using ScottPlot;
using System;
using System.Collections.Generic;
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
@ -6,44 +7,36 @@ using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace Elwig.Helpers.Export {
public class OdsFile : IDisposable, IAsyncDisposable {
public class OdsFile : IDisposable {
protected readonly string FileName;
protected readonly ZipArchive ZipArchive;
protected StreamWriter? Content;
private readonly List<string> _tables;
public OdsFile(string filename) {
FileName = filename;
File.Delete(filename);
ZipArchive = ZipFile.Open(FileName, ZipArchiveMode.Create); ;
Content = null;
ZipArchive = ZipFile.Open(FileName, ZipArchiveMode.Create);
_tables = new List<string>();
}
public void Dispose() {
DisposeAsync().GetAwaiter().GetResult();
}
public async ValueTask DisposeAsync() {
await AddTrailer();
Content?.Close();
Content?.DisposeAsync();
AddTrailer().GetAwaiter().GetResult();
ZipArchive?.Dispose();
GC.SuppressFinalize(this);
}
private async Task AddHeader() {
var mimetype = ZipArchive.CreateEntry("mimetype", CompressionLevel.NoCompression);
using (var stream = mimetype.Open()) {
using var writer = new StreamWriter(stream, Utils.UTF8);
using (var writer = new StreamWriter(mimetype.Open(), Utils.UTF8)) {
await writer.WriteAsync("application/vnd.oasis.opendocument.spreadsheet");
}
var manifest = ZipArchive.CreateEntry("META-INF/manifest.xml");
using (var stream = manifest.Open()) {
using var writer = new StreamWriter(stream, Utils.UTF8);
using (var writer = new StreamWriter(manifest.Open(), Utils.UTF8)) {
await writer.WriteAsync("""
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.3">
@ -51,14 +44,14 @@ namespace Elwig.Helpers.Export {
<manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/>
<manifest:file-entry manifest:full-path="styles.xml" manifest:media-type="text/xml"/>
<manifest:file-entry manifest:full-path="meta.xml" manifest:media-type="text/xml"/>
<manifest:file-entry manifest:full-path="settings.xml" manifest:media-type="text/xml"/>
</manifest:manifest>
""");
}
var styles = ZipArchive.CreateEntry("styles.xml");
using (var stream = styles.Open()) {
using var writer = new StreamWriter(stream, Utils.UTF8);
using (var writer = new StreamWriter(styles.Open(), Utils.UTF8)) {
await writer.WriteAsync("""
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<office:document-styles xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" office:version="1.3">
@ -68,8 +61,7 @@ namespace Elwig.Helpers.Export {
}
var meta = ZipArchive.CreateEntry("meta.xml");
using (var stream = meta.Open()) {
using var writer = new StreamWriter(stream, Utils.UTF8);
using (var writer = new StreamWriter(meta.Open(), Utils.UTF8)) {
var now = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
await writer.WriteAsync($"""
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
@ -119,7 +111,51 @@ namespace Elwig.Helpers.Export {
private async Task AddTrailer() {
if (Content == null) await AddHeader();
if (Content == null) return;
await Content.WriteAsync(" </office:spreadsheet>\r\n </office:body>\r\n</office:document-content>\r\n");
await Content.WriteAsync("""
</office:spreadsheet>
</office:body>
</office:document-content>
""");
Content.Close();
Content.Dispose();
Content = null;
var settings = ZipArchive.CreateEntry("settings.xml");
using (var writer = new StreamWriter(settings.Open(), Utils.UTF8)) {
await writer.WriteAsync("""
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<office:document-settings xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" office:version="1.3">
<office:settings>
<config:config-item-set config:name="ooo:view-settings">
<config:config-item-map-indexed config:name="Views">
<config:config-item-map-entry>
<config:config-item-map-named config:name="Tables">
""");
foreach (var tbl in _tables) {
await writer.WriteAsync($"""
<config:config-item-map-entry config:name="{tbl}">
<config:config-item config:name="VerticalSplitMode" config:type="short">2</config:config-item>
<config:config-item config:name="VerticalSplitPosition" config:type="int">3</config:config-item>
<config:config-item config:name="PositionBottom" config:type="int">3</config:config-item>
</config:config-item-map-entry>
""");
}
await writer.WriteAsync("""
</config:config-item-map-named>
</config:config-item-map-entry>
</config:config-item-map-indexed>
</config:config-item-set>
</office:settings>
</office:document-settings>
""");
}
}
public async Task AddTable<T>(DataTable<T> table) {
@ -127,6 +163,8 @@ namespace Elwig.Helpers.Export {
if (Content == null) return;
var totalSpan = table.ColumnSpans.Sum(s => s.Item2);
_tables.Add(table.FullName);
await Content.WriteAsync(
$" <table:table table:name=\"{table.FullName}\">\r\n" +
$" <table:table-column table:default-cell-style-name=\"default\"/>\r\n" +