Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement async #74

Merged
merged 5 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x
dotnet-version: 6.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
Expand Down
30 changes: 15 additions & 15 deletions src/MiniWord/Extensions/OpenXmlExtension.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace MiniSoftware.Extensions
锘縩amespace MiniSoftware.Extensions
{
using DocumentFormat.OpenXml.Wordprocessing;
using System;
Expand All @@ -12,10 +12,10 @@ namespace MiniSoftware.Extensions
internal static class OpenXmlExtension
{
/// <summary>
/// 高级搜索:得到段落里面的连续字符串
/// 楂樼骇鎼滅储锛氬緱鍒版钀介噷闈㈢殑杩炵画瀛楃涓�
/// </summary>
/// <param name="paragraph">段落</param>
/// <returns>Item1:连续文本;Item2:块;Item3:块文本</returns>
/// <param name="paragraph">娈佃惤</param>
/// <returns>Item1锛氳繛缁枃鏈紱Item2锛氬潡锛汭tem3锛氬潡鏂囨湰</returns>
internal static List<Tuple<string, List<Run>, List<Text>>> GetContinuousString(this Paragraph paragraph)
{
List<Tuple<string, List<Run>, List<Text>>> tuples = new List<Tuple<string, List<Run>, List<Text>>>();
Expand All @@ -26,13 +26,13 @@ internal static List<Tuple<string, List<Run>, List<Text>>> GetContinuousString(t
var runs = new List<Run>();
var texts = new List<Text>();

//段落:所有子级
//娈佃惤锛氭墍鏈夊瓙绾�
foreach (var pChildElement in paragraph.ChildElements)
{
//
//鍧�
if (pChildElement is Run run)
{
//文本块
//鏂囨湰鍧�
if (run.IsText())
{
var text = run.GetFirstChild<Text>();
Expand All @@ -50,10 +50,10 @@ internal static List<Tuple<string, List<Run>, List<Text>>> GetContinuousString(t
texts = new List<Text>();
}
}
//公式,书签...
//鍏紡锛屼功绛�...
else
{
//跳过的类型
//璺宠繃鐨勭被鍨�
if (pChildElement is BookmarkStart || pChildElement is BookmarkEnd)
{

Expand Down Expand Up @@ -81,16 +81,16 @@ internal static List<Tuple<string, List<Run>, List<Text>>> GetContinuousString(t
}

/// <summary>
/// 整理字符串到连续字符串块中
/// 鏁寸悊瀛楃涓插埌杩炵画瀛楃涓插潡涓�
/// </summary>
/// <param name="texts">连续字符串块</param>
/// <param name="text">待整理字符串</param>
/// <param name="texts">杩炵画瀛楃涓插潡</param>
/// <param name="text">寰呮暣鐞嗗瓧绗︿覆</param>
internal static void TrimStringToInContinuousString(this IEnumerable<Text> texts, string text)
{
/*
//假如块为:[A][BC][DE][FG][H]
//假如替换:[AB][E][GH]
//优化块为:[AB][C][DE][FGH][]
//鍋囧鍧椾负锛歔A][BC][DE][FG][H]
//鍋囧鏇挎崲锛歔AB][E][GH]
//浼樺寲鍧椾负锛歔AB][C][DE][FGH][]
*/

var allTxtx = string.Concat(texts.SelectMany(o => o.Text));
Expand Down
73 changes: 47 additions & 26 deletions src/MiniWord/MiniWord.Implment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ namespace MiniSoftware
using A = DocumentFormat.OpenXml.Drawing;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
using System.Threading.Tasks;
using System.Threading;

public static partial class MiniWord
{
Expand All @@ -25,22 +27,39 @@ private static void SaveAsByTemplateImpl(Stream stream, byte[] template, Diction
using (var ms = new MemoryStream())
{
ms.Write(template, 0, template.Length);
ms.Position = 0;
using (var docx = WordprocessingDocument.Open(ms, true))
{
var hc = docx.MainDocumentPart.HeaderParts.Count();
var fc = docx.MainDocumentPart.FooterParts.Count();
for (int i = 0; i < hc; i++)
docx.MainDocumentPart.HeaderParts.ElementAt(i).Header.Generate(docx, value);
for (int i = 0; i < fc; i++)
docx.MainDocumentPart.FooterParts.ElementAt(i).Footer.Generate(docx, value);
docx.MainDocumentPart.Document.Body.Generate(docx, value);
docx.Save();
}
bytes = ms.ToArray();
bytes = WriteToByte(data, ms);
}
stream.Write(bytes, 0, bytes.Length);
}

private static async Task SaveAsByTemplateImplAsync(Stream stream, byte[] template, Dictionary<string, object> data,CancellationToken token)
{
byte[] bytes = null;
using (var ms = new MemoryStream())
{
await ms.WriteAsync(template, 0, template.Length, token);
bytes = WriteToByte(data, ms);
}
await stream.WriteAsync(bytes, 0, bytes.Length,token);
}

private static byte[] WriteToByte(Dictionary<string, object> value, MemoryStream ms)
{
ms.Position = 0;
using (var docx = WordprocessingDocument.Open(ms, true))
{
var hc = docx.MainDocumentPart.HeaderParts.Count();
var fc = docx.MainDocumentPart.FooterParts.Count();
for (int i = 0; i < hc; i++)
docx.MainDocumentPart.HeaderParts.ElementAt(i).Header.Generate(docx, value);
for (int i = 0; i < fc; i++)
docx.MainDocumentPart.FooterParts.ElementAt(i).Footer.Generate(docx, value);
docx.MainDocumentPart.Document.Body.Generate(docx, value);
docx.Save();
}
return ms.ToArray();
}

private static void Generate(this OpenXmlElement xmlElement, WordprocessingDocument docx, Dictionary<string, object> tags)
{
// avoid {{tag}} like <t>{</t><t>{</t>
Expand All @@ -53,14 +72,14 @@ private static void Generate(this OpenXmlElement xmlElement, WordprocessingDocum
{
foreach (var table in tables)
{
var trs = table.Descendants<TableRow>().ToArray(); // remember toarray or system will loop OOM;
var trs = table.Descendants<TableRow>().ToArray(); // remember toarray otherwise system will loop OOM;

foreach (var tr in trs)
{
var innerText = tr.InnerText.Replace("{{foreach", "").Replace("endforeach}}", "")
.Replace("{{if(", "").Replace(")if", "").Replace("endif}}", "");
var matchs = (Regex.Matches(innerText, "(?<={{).*?\\..*?(?=}})")
.Cast<Match>().GroupBy(x => x.Value).Select(varGroup => varGroup.First().Value)).ToArray();
var matchs = Regex.Matches(innerText, "(?<={{).*?\\..*?(?=}})")
.Cast<Match>().GroupBy(x => x.Value).Select(varGroup => varGroup.First().Value).ToArray();
if (matchs.Length > 0)
{
var listKeys = matchs.Select(s => s.Split('.')[0]).Distinct().ToArray();
Expand All @@ -76,15 +95,8 @@ private static void Generate(this OpenXmlElement xmlElement, WordprocessingDocum

foreach (Dictionary<string, object> es in list)
{
var dic = new Dictionary<string, object>(); //TODO: optimize

var dic = es.ToDictionary(e => $"{listKey}.{e.Key}", e => e.Value);
var newTr = tr.CloneNode(true);
foreach (var e in es)
{
var dicKey = $"{listKey}.{e.Key}";
dic.Add(dicKey, e.Value);
}

ReplaceStatements(newTr, tags: dic);

ReplaceText(newTr, docx, tags: dic);
Expand Down Expand Up @@ -356,8 +368,7 @@ private static void ReplaceText(OpenXmlElement xmlElement, WordprocessingDocumen
{
if (forTags.Any(forTag => forTag.Value.Keys.Any(dictKey =>
{
var innerTag = "{{" + tag.Key + "." + dictKey + "}}";
return t.Text.Contains(innerTag);
return t.Text.Contains($@"{{{{{tag.Key}.{dictKey}}}}}");
})))
{
isMatch = true;
Expand Down Expand Up @@ -700,5 +711,15 @@ private static byte[] GetBytes(string path)
return ms.ToArray();
}
}

private static async Task<byte[]> GetByteAsync(string path)
{
using (var st = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, true))
using (var ms = new MemoryStream())
{
await st.CopyToAsync(ms);
return ms.ToArray();
}
}
}
}
26 changes: 26 additions & 0 deletions src/MiniWord/MiniWord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ namespace MiniSoftware
{
using DocumentFormat.OpenXml.Office2013.Excel;
using MiniSoftware.Extensions;
using MiniSoftware.Utility;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Dynamic;
using System.IO;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;

public static partial class MiniWord
{
Expand All @@ -31,5 +35,27 @@ public static void SaveAsByTemplate(this Stream stream, byte[] templateBytes, ob
{
SaveAsByTemplateImpl(stream, templateBytes, value.ToDictionary());
}

public static async Task SaveAsByTemplateAsync(this Stream stream, byte[] templateBytes, object value,CancellationToken token = default(CancellationToken))
{
await SaveAsByTemplateImplAsync(stream, templateBytes, value.ToDictionary(),token).ConfigureAwait(false);
}

public static async Task SaveAsByTemplateAsync(this Stream stream, string templatePath, object value,CancellationToken token = default(CancellationToken))
{
await SaveAsByTemplateImplAsync(stream, await GetByteAsync(templatePath), value.ToDictionary(),token).ConfigureAwait(false);
}

public static async Task SaveAsByTemplateAsync(string path, string templatePath, object value,CancellationToken token = default(CancellationToken))
{
using (var stream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, true))
await SaveAsByTemplateImplAsync(stream, await GetByteAsync(templatePath), value.ToDictionary(),token);
}

public static async Task SaveAsByTemplateAsync(string path, byte[] templateBytes, object value,CancellationToken token = default(CancellationToken))
{
using (var stream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, true))
await SaveAsByTemplateImplAsync(stream, templateBytes, value.ToDictionary(),token);
}
}
}
1 change: 1 addition & 0 deletions src/MiniWord/Utility/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.ComponentModel;
using System.Dynamic;
using System.IO;
using System.Threading.Tasks;

internal static partial class Helpers
{
Expand Down
Loading
Loading