using Elwig.Models.Dtos;
using System;
using System.Collections.Generic;
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
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 {
protected readonly string FileName;
protected readonly ZipArchive ZipArchive;
protected StreamWriter? Content;
public OdsFile(string filename) {
FileName = filename;
File.Delete(filename);
ZipArchive = ZipFile.Open(FileName, ZipArchiveMode.Create); ;
Content = null;
}
public void Dispose() {
DisposeAsync().GetAwaiter().GetResult();
}
public async ValueTask DisposeAsync() {
await AddTrailer();
Content?.Close();
Content?.DisposeAsync();
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);
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);
await writer.WriteAsync("""
""");
}
var styles = ZipArchive.CreateEntry("styles.xml");
using (var stream = styles.Open()) {
using var writer = new StreamWriter(stream, Utils.UTF8);
await writer.WriteAsync("""
""");
}
var meta = ZipArchive.CreateEntry("meta.xml");
using (var stream = meta.Open()) {
using var writer = new StreamWriter(stream, Utils.UTF8);
var now = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
await writer.WriteAsync($"""
Elwig {App.Version}
Elwig
Elwig
{now}
{now}
""");
}
var content = ZipArchive.CreateEntry("content.xml");
Content = new StreamWriter(content.Open(), Utils.UTF8);
await Content.WriteAsync("""
""");
}
private async Task AddTrailer() {
if (Content == null) await AddHeader();
if (Content == null) return;
await Content.WriteAsync(" \r\n \r\n\r\n");
}
public async Task AddTable(DataTable table) {
if (Content == null) await AddHeader();
if (Content == null) return;
var totalSpan = table.ColumnSpans.Sum(s => s.Item2);
await Content.WriteAsync(
$" \r\n" +
$" \r\n" +
$" \r\n" +
FormatCell(table.FullName, colSpan: totalSpan, style: "header") +
$" \r\n" +
$" \r\n" +
$" \r\n" +
$" \r\n" +
$" \r\n");
foreach (var (name, span) in table.ColumnSpans) {
await Content.WriteAsync(FormatCell(name, colSpan: span, style: "th"));
}
await Content.WriteAsync(" \r\n");
foreach (var row in table.GetData()) {
await FormatRow(row);
}
await Content.WriteAsync(" \r\n");
}
protected async Task FormatRow(IEnumerable