diff --git a/src/MiniWord/MiniWord.Implment.cs b/src/MiniWord/MiniWord.Implment.cs index 11ada1e..ffe2a6f 100644 --- a/src/MiniWord/MiniWord.Implment.cs +++ b/src/MiniWord/MiniWord.Implment.cs @@ -95,7 +95,7 @@ private static void Generate(this OpenXmlElement xmlElement, WordprocessingDocum foreach (Dictionary es in list) { - var dic = es.ToDictionary(key => $"{listKey}.{key}", item=>item.Value); + var dic = es.ToDictionary(e => $"{listKey}.{e.Key}", e => e.Value); var newTr = tr.CloneNode(true); ReplaceStatements(newTr, tags: dic); diff --git a/src/MiniWord/MiniWord.cs b/src/MiniWord/MiniWord.cs index 675e8e1..3ca2706 100644 --- a/src/MiniWord/MiniWord.cs +++ b/src/MiniWord/MiniWord.cs @@ -3,6 +3,7 @@ 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; @@ -47,14 +48,14 @@ public static void SaveAsByTemplate(this Stream stream, byte[] templateBytes, ob public static async Task SaveAsByTemplateAsync(string path, string templatePath, object value,CancellationToken token = default(CancellationToken)) { - using (var stream = FileHelper.CreateAsync(path)) - await SaveAsByTemplateImplAsync(await stream, await GetByteAsync(templatePath), value.ToDictionary(),token); + 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 = FileHelper.CreateAsync(path)) - await SaveAsByTemplateImplAsync(await stream, templateBytes, value.ToDictionary(),token); + using (var stream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, true)) + await SaveAsByTemplateImplAsync(stream, templateBytes, value.ToDictionary(),token); } } } \ No newline at end of file diff --git a/src/MiniWord/Utility/FileAyncExtension.cs b/src/MiniWord/Utility/FileAyncExtension.cs deleted file mode 100644 index 8bd4081..0000000 --- a/src/MiniWord/Utility/FileAyncExtension.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace MiniSoftware.Utility -{ - using System.IO; - using System.Threading.Tasks; - internal static class FileHelper{ - internal static async Task CreateAsync(string path) - { - using (var stream = File.Create(path)) - { - return await Task.FromResult(stream); - } - } - } -} \ No newline at end of file diff --git a/tests/MiniWordTests/IssueTestsAsync.cs b/tests/MiniWordTests/IssueTestsAsync.cs new file mode 100644 index 0000000..1667da6 --- /dev/null +++ b/tests/MiniWordTests/IssueTestsAsync.cs @@ -0,0 +1,876 @@ +using MiniSoftware; +using System; +using System.Collections.Generic; +using Xunit; +using System.Dynamic; +using DocumentFormat.OpenXml.Wordprocessing; +using System.Threading.Tasks; + +namespace MiniWordTests +{ + public class IssueTestsAsync + { + [Fact] + public async Task TestIssue69() + { + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestIssue47.docx"); + var value = new Dictionary() + { + { "line",new List> + { + new Dictionary + { + {"num", "1"}, + {"spc", "Specification1"}, + {"desc", "Description1"}, + {"qty", "10"}, + {"up", "20.00"}, + {"tax_rate", "0.20"}, + {"tax_amount", "4.00"} + }, + new Dictionary + { + {"num", "2"}, + {"spc", "Specification2"}, + {"desc", "Description2"}, + {"qty", "5"}, + {"up", "30.00"}, + {"tax_rate", "0.15"}, + {"tax_amount", "2.25"} + } + } + } + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + // TODO: waiting solution + //var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + //Assert.Contains(@"MiniWord", xml); + } + } + + [Fact] + public async Task TaskSplitTag() + { + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestDemo04.docx"); + var value = new Dictionary + { + ["title"] = "Hello MiniWord", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"MiniWord", xml); + } + } + + /// + /// [Text color multiple tags format error · Issue #37 · mini-software/MiniWord] + /// (https://github.com/mini-software/MiniWord/issues/37) + /// + [Fact] + public async Task TestIssue37() + { + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestIssue37.docx"); + var value = new Dictionary + { + ["Content"] = "Test", + ["Content2"] = "Test2", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Test", xml); + Assert.Contains(@"Test2", xml); + } + + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestIssue37.docx"); + var value = new Dictionary + { + ["Content"] = new MiniWordHyperLink() + { + Url = "https://google.com", + Text = "Test1!!" + }, + ["Content2"] = new MiniWordHyperLink() + { + Url = "https://google.com", + Text = "Test2!!" + }, + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Test", xml); + Assert.Contains(@"Test2", xml); + } + } + + [Fact] + public async Task TestDemo04() + { + var outputPath = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestDemo04.docx"); + var value = new Dictionary() { ["title"] = "Hello MiniWord" }; + await MiniWord.SaveAsByTemplateAsync(outputPath, templatePath, value); + } + + [Fact] + public async Task TestDemo04_new() + { + var outputPath = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestDemo04.docx"); + var value = new { title = "Hello MiniWord" }; + await MiniWord.SaveAsByTemplateAsync(outputPath, templatePath, value); + } + + + [Fact] + public async Task TestIssue18() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestIssue18.docx"); + + { + var value = new Dictionary() + { + ["title"] = "FooCompany", + ["managers"] = new List> { + new Dictionary{{"name","Jack"},{ "department", "HR" } }, + new Dictionary {{ "name", "Loan"},{ "department", "IT" } } + }, + ["employees"] = new List> { + new Dictionary{{ "name", "Wade" },{ "department", "HR" } }, + new Dictionary {{ "name", "Felix" },{ "department", "HR" } }, + new Dictionary{{ "name", "Eric" },{ "department", "IT" } }, + new Dictionary {{ "name", "Keaton" },{ "department", "IT" } } + } + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Keaton", xml); + Assert.Contains(@"Eric", xml); + } + + //Strong type + { + var value = new + { + title = "FooCompany", + managers = new[] + { + new {name="Jack",department="HR" }, + new {name="Loan",department="IT" }, + }, + employees = new[] + { + new {name="Jack",department="HR" }, + new {name="Loan",department="HR" }, + new {name="Eric",department="IT" }, + new {name="Keaton",department="IT" }, + }, + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Keaton", xml); + Assert.Contains(@"Eric", xml); + } + + //Strong type + { + Foo value = new Foo() + { + title = "FooCompany", + managers = new List() + { + new User (){ name="Jack",department="HR"}, + new User (){ name="Loan",department="IT"}, + }, + employees = new List() + { + new User (){ name="Jack",department="HR"}, + new User (){ name="Loan",department="HR"}, + new User (){ name="Eric",department="IT"}, + new User (){ name="Keaton",department="IT"}, + }, + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Keaton", xml); + Assert.Contains(@"Eric", xml); + } + } + + /// + /// [Split template string like `{{Tag}}` problem · Issue #17 · mini-software/MiniWord] + /// (https://github.com/mini-software/MiniWord/issues/17) + /// + [Fact] + public async Task TestIssue17() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestIssue17.docx"); + var value = new Dictionary() + { + ["Content"] = "Test", + ["Content2"] = "Test2", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Test", xml); + Assert.Contains(@"Test2", xml); + } + + /// + /// [Split template string like `{{Tag}}` problem · Issue #17 · mini-software/MiniWord] + /// (https://github.com/mini-software/MiniWord/issues/17) + /// + [Fact] + public async Task TestIssue17_new() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestIssue17.docx"); + var value = new + { + Content = "Test", + Content2 = "Test2", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Test", xml); + Assert.Contains(@"Test2", xml); + } + + + /// + /// [Support table generate · Issue #13 · mini-software/MiniWord] + /// (https://github.com/mini-software/MiniWord/issues/13) + /// + [Fact] + public async Task TestIssue13() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestExpenseDemo.docx"); + var value = new Dictionary() + { + ["TripHs"] = new List> + { + new Dictionary + { + { "sDate",DateTime.Parse("2022-09-08 08:30:00")}, + { "eDate",DateTime.Parse("2022-09-08 15:00:00")}, + { "How","Discussion requirement part1"}, + { "Photo",new MiniWordPicture() { Path = PathHelper.GetFile("DemoExpenseMeeting02.png"), Width = 160, Height = 90 }}, + }, + new Dictionary + { + { "sDate",DateTime.Parse("2022-09-09 08:30:00")}, + { "eDate",DateTime.Parse("2022-09-09 17:00:00")}, + { "How","Discussion requirement part2 and development"}, + { "Photo",new MiniWordPicture() { Path = PathHelper.GetFile("DemoExpenseMeeting01.png"), Width = 160, Height = 90 }}, + }, + } + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + //System.Diagnostics.Process.Start("explorer.exe", path); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Discussion requirement part2 and development", xml); + Assert.Contains(@"Discussion requirement part1", xml); + } + + /// + /// [Support table generate · Issue #13 · mini-software/MiniWord] + /// (https://github.com/mini-software/MiniWord/issues/13) + /// + [Fact] + public async Task TestIssue13_new() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestExpenseDemo.docx"); + var value = new + { + TripHs = new List> + { + new Dictionary + { + { "sDate",DateTime.Parse("2022-09-08 08:30:00")}, + { "eDate",DateTime.Parse("2022-09-08 15:00:00")}, + { "How","Discussion requirement part1"}, + { "Photo",new MiniWordPicture() { Path = PathHelper.GetFile("DemoExpenseMeeting02.png"), Width = 160, Height = 90 }}, + }, + new Dictionary + { + { "sDate",DateTime.Parse("2022-09-09 08:30:00")}, + { "eDate",DateTime.Parse("2022-09-09 17:00:00")}, + { "How","Discussion requirement part2 and development"}, + { "Photo",new MiniWordPicture() { Path = PathHelper.GetFile("DemoExpenseMeeting01.png"), Width = 160, Height = 90 }}, + }, + } + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + //System.Diagnostics.Process.Start("explorer.exe", path); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Discussion requirement part2 and development", xml); + Assert.Contains(@"Discussion requirement part1", xml); + } + + [Fact] + public async Task TestDemo01_Tag_Text() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestExpenseDemo.docx"); + var value = new Dictionary() + { + ["Name"] = "Jack", + ["Department"] = "IT Department", + ["Purpose"] = "Shanghai site needs a new system to control HR system.", + ["StartDate"] = DateTime.Parse("2022-09-07 08:30:00"), + ["EndDate"] = DateTime.Parse("2022-09-15 15:30:00"), + ["Approved"] = true, + ["Total_Amount"] = 123456, + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + } + + + [Fact] + public async Task TestDemo01_Tag_Text_new() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestExpenseDemo.docx"); + var value = new + { + Name = "Jack", + Department = "IT Department", + Purpose = "Shanghai site needs a new system to control HR system.", + StartDate = DateTime.Parse("2022-09-07 08:30:00"), + EndDate = DateTime.Parse("2022-09-15 15:30:00"), + Approved = true, + Total_Amount = 123456, + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + } + + /// + /// [System.InvalidOperationException: 'The parent of this element is null.' · Issue #12 · mini-software/MiniWord](https://github.com/mini-software/MiniWord/issues/12) + /// + [Fact] + public async Task TestIssue12() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestBasicFill.docx"); + var value = new Dictionary() + { + ["Company_Name"] = "MiniSofteware\n", + ["Name"] = "Jack", + ["CreateDate"] = new DateTime(2021, 01, 01), + ["VIP"] = true, + ["Points"] = 123, + ["APP"] = "Demo APP\n", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"MiniSofteware", xml); + Assert.Contains(@"", xml); + } + + /// + /// [System.InvalidOperationException: 'The parent of this element is null.' · Issue #12 · mini-software/MiniWord](https://github.com/mini-software/MiniWord/issues/12) + /// + [Fact] + public async Task TestIssue12_dynamic() + { + + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestBasicFill.docx"); + dynamic value = new ExpandoObject(); + value.Company_Name = "MiniSofteware\n"; + value.Name = "Jack"; + value.CreateDate = new DateTime(2021, 01, 01); + value.VIP = true; + value.Points = 123; + value.APP = "Demo APP\n"; + + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"MiniSofteware", xml); + Assert.Contains(@"", xml); + } + + /// + /// [System.InvalidOperationException: 'The parent of this element is null.' · Issue #12 · mini-software/MiniWord](https://github.com/mini-software/MiniWord/issues/12) + /// + [Fact] + public async Task TestIssue12_new() + { + + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestBasicFill.docx"); + object value = new + { + Company_Name = "MiniSofteware\n", + Name = "Jack", + CreateDate = new DateTime(2021, 01, 01), + VIP = true, + Points = 123, + APP = "Demo APP\n", + }; + + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"MiniSofteware", xml); + Assert.Contains(@"", xml); + } + + [Fact] + public async Task TestIssueDemo03() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestDemo02.docx"); + var value = new Dictionary() + { + ["FullName"] = "Julian Anderson", + ["Title"] = "IT Manager", + ["Phone"] = "+86 1234567890", + ["Mail"] = "shps95100@gmail.com", + ["Education"] = "Michigan State University | From Aug 2013 to May 2015", + ["Major"] = "Computer Science", + ["Favorites"] = "Music、Programing、Design", + ["Skills"] = new[] { "- Photoshop", "- InDesign", "- MS Office", "- HTML 5", "- CSS 3" }, + ["Address"] = "1234, White Home, Road-12/ABC Street-13, New York, USA, 12345", + ["AboutMe"] = "Hi, I’m Julian Anderson dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled the industry's standard dummy.", + ["Birthday"] = "1993-09-26", + ["Experiences"] = @"# SENIOR UI/UX DEVELOPER & DESIGNER +◼ The Matrix Media Limited | From May 2013 to May 2015 +Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took. + +◼ JUNIOR UI/UX DEVELOPER & DESIGNER +Linux OS Interface Limited | From Jan 2010 to Feb 2013 +Lorem Ipsum has been the industry's standard dummy text +ever since the 1500s, when an unknown printer took. + +◼ TEAM LEADER & CORE GRAPHIC DESIGNER +Apple OS Interface Limited | From Jan 2008 to Feb 2010 +Lorem Ipsum has been the industry's standard dummy text +ever since the 1500s, when an unknown printer took. + +◼ JUNIOR UI/UX DEVELOPER & DESIGNER +Apple OS Interface Limited | From Jan 2008 to Feb 2010 +Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took. + +◼ JUNIOR UI/UX DEVELOPER & DESIGNER +Apple OS Interface Limited | From Jan 2008 to Feb 2010 +Lorem Ipsum has been the industry's standard dummy text +ever since the 1500s, when an unknown printer took. +", + ["Image"] = new MiniWordPicture() { Path = PathHelper.GetFile("demo01.png"), Width = 160, Height = 90 }, + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + //System.Diagnostics.Process.Start("explorer.exe", path); + } + + [Fact] + public async Task TestIssueDemo03_dynamic() + { + + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestDemo02.docx"); + dynamic value = new ExpandoObject(); + value.FullName = "Julian Anderson"; + value.Title = "IT Manager"; + value.Phone = "+86 1234567890"; + value.Mail = "shps95100@gmail.com"; + value.Education = "Michigan State University | From Aug 2013 to May 2015"; + value.Major = "Computer Science"; + value.Favorites = "Music、Programing、Design"; + value.Skills = new[] { "- Photoshop", "- InDesign", "- MS Office", "- HTML 5", "- CSS 3" }; + value.Address = "1234, White Home, Road-12/ABC Street-13, New York, USA, 12345"; + value.AboutMe = "Hi, I’m Julian Anderson dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled the industry's standard dummy."; + value.Birthday = "1993-09-26"; + value.Experiences = @"# SENIOR UI/UX DEVELOPER & DESIGNER + ◼ The Matrix Media Limited | From May 2013 to May 2015 + Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took. + + ◼ JUNIOR UI/UX DEVELOPER & DESIGNER + Linux OS Interface Limited | From Jan 2010 to Feb 2013 + Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took. + + ◼ TEAM LEADER & CORE GRAPHIC DESIGNER + Apple OS Interface Limited | From Jan 2008 to Feb 2010 + Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took. + + ◼ JUNIOR UI/UX DEVELOPER & DESIGNER + Apple OS Interface Limited | From Jan 2008 to Feb 2010 + Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took. + + ◼ JUNIOR UI/UX DEVELOPER & DESIGNER + Apple OS Interface Limited | From Jan 2008 to Feb 2010 + Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took. + "; + value.Image = new MiniWordPicture() { Path = PathHelper.GetFile("demo01.png"), Width = 160, Height = 90 }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + //System.Diagnostics.Process.Start("explorer.exe", path); + } + + /// + /// [support array list string to generate multiple row · Issue #11 · mini-software/MiniWord] + /// (https://github.com/mini-software/MiniWord/issues/11) + /// + [Fact] + public async Task TestIssue11() + { + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestIssue11.docx"); + var value = new Dictionary() + { + ["managers"] = new[] { "Jack", "Alan" }, + ["employees"] = new[] { "Mike", "Henry" }, + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains("Jack", xml); + } + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestIssue11.docx"); + var value = new Dictionary() + { + ["managers"] = new List { "Jack", "Alan" }, + ["employees"] = new List { "Mike", "Henry" }, + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains("Jack", xml); + } + } + + /// + /// [support array list string to generate multiple row · Issue #11 · mini-software/MiniWord] + /// (https://github.com/mini-software/MiniWord/issues/11) + /// + [Fact] + public async Task TestIssue11_new() + { + //{ + // var path = PathHelper.GetTempFilePath(); + // var templatePath = PathHelper.GetFile("TestIssue11.docx"); + // var value = new + // { + // managers = new[] { "Jack", "Alan" }, + // employees = new[] { "Mike", "Henry" }, + // }; + // await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + // var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + // Assert.Contains("Jack", xml); + //} + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestIssue11.docx"); + var value = new + { + managers = new List { "Jack", "Alan" }, + employees = new List { "Mike", "Henry" }, + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains("Jack", xml); + } + } + + + /// + /// [Support image · Issue #3 · mini-software/MiniWord](https://github.com/mini-software/MiniWord/issues/3) + /// + [Fact] + public async Task TestIssue3() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestBasicImage.docx"); + var value = new Dictionary() + { + ["Logo"] = new MiniWordPicture() { Path = PathHelper.GetFile("DemoLogo.png"), Width = 180, Height = 180 } + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains("", xml); + } + + /// + /// [Fuzzy Regex replace similar key · Issue #5 · mini-software/MiniWord](https://github.com/mini-software/MiniWord/issues/5) + /// + [Fact] + public async Task TestIssue5() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestBasicFill.docx"); + var value = new Dictionary() + { + ["Name"] = new MiniWordHyperLink() + { + Url = "https://google.com", + Text = "測試連結!!" + }, + ["Company_Name"] = "MiniSofteware", + ["CreateDate"] = new DateTime(2021, 01, 01), + ["VIP"] = true, + ["Points"] = 123, + ["APP"] = "Demo APP", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + //Console.WriteLine(path); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.DoesNotContain("Jack Demo APP Account Data", xml); + Assert.Contains("MiniSofteware Demo APP Account Data", xml); + Assert.Contains("MiniSofteware Demo APP Account Data", xml); + Assert.Contains("() + { + ["Name"] = new List(){ + new MiniWordHyperLink(){ + Url = "https://google.com", + Text = "測試連結22!!" + }, + new MiniWordHyperLink(){ + Url = "https://google1.com", + Text = "測試連結11!!" + } + }, + ["Company_Name"] = "MiniSofteware", + ["CreateDate"] = new DateTime(2021, 01, 01), + ["VIP"] = true, + ["Points"] = 123, + ["APP"] = "Demo APP", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + //Console.WriteLine(path); + var docXml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.DoesNotContain("Jack Demo APP Account Data", docXml); + Assert.Contains("MiniSofteware Demo APP Account Data", docXml); + Assert.Contains("MiniSofteware Demo APP Account Data", docXml); + Assert.Contains("() + { + ["Name"] = new MiniWordHyperLink[]{ + new MiniWordHyperLink(){ + Url = "https://google.com", + Text = "測試連結22!!" + }, + new MiniWordHyperLink(){ + Url = "https://google1.com", + Text = "測試連結11!!" + } + }, + ["Company_Name"] = "MiniSofteware", + ["CreateDate"] = new DateTime(2021, 01, 01), + ["VIP"] = true, + ["Points"] = 123, + ["APP"] = "Demo APP", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + + var docXml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.DoesNotContain("Jack Demo APP Account Data", docXml); + Assert.Contains("MiniSofteware Demo APP Account Data", docXml); + Assert.Contains("MiniSofteware Demo APP Account Data", docXml); + Assert.Contains("() + { + ["Name"] = new[]{ + new MiniWordHyperLink(){ + Url = "https://google.com", + Text = "測試連結22!!" + }, + new MiniWordHyperLink(){ + Url = "https://google1.com", + Text = "測試連結11!!" + } + }, + ["Company_Name"] = "MiniSofteware", + ["CreateDate"] = new DateTime(2021, 01, 01), + ["VIP"] = true, + ["Points"] = 123, + ["APP"] = "Demo APP", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + + var docXml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.DoesNotContain("Jack Demo APP Account Data", docXml); + Assert.Contains("MiniSofteware Demo APP Account Data", docXml); + Assert.Contains("MiniSofteware Demo APP Account Data", docXml); + Assert.Contains(" + /// [Fuzzy Regex replace similar key · Issue #5 · mini-software/MiniWord](https://github.com/mini-software/MiniWord/issues/5) + /// + [Fact] + public async Task TestIssue5_new() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestBasicFill.docx"); + var value = new + { + Name = new MiniWordHyperLink() + { + Url = "https://google.com", + Text = "測試連結!!" + }, + Company_Name = "MiniSofteware", + CreateDate = new DateTime(2021, 01, 01), + VIP = true, + Points = 123, + APP = "Demo APP", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + //Console.WriteLine(path); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.DoesNotContain("Jack Demo APP Account Data", xml); + Assert.Contains("MiniSofteware Demo APP Account Data", xml); + Assert.Contains(" + /// [Paragraph replace by tag · Issue #4 · mini-software/MiniWord](https://github.com/mini-software/MiniWord/issues/4) + /// + [Fact] + public async Task TestIssue4() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestBasicFill.docx"); + var value = new Dictionary() + { + ["Company_Name"] = "MiniSofteware", + ["Name"] = "Jack", + ["CreateDate"] = new DateTime(2021, 01, 01), + ["VIP"] = true, + ["Points"] = 123, + ["APP"] = "Demo APP", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + } + + /// + /// [Paragraph replace by tag · Issue #4 · mini-software/MiniWord](https://github.com/mini-software/MiniWord/issues/4) + /// + [Fact] + public async Task TestIssue4_new() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestBasicFill.docx"); + var value = new + { + Company_Name = "MiniSofteware", + Name = "Jack", + CreateDate = new DateTime(2021, 01, 01), + VIP = true, + Points = 123, + APP = "Demo APP", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + } + [Fact] + public async Task TestColor() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestBasicFill.docx"); + var value = new + { + Company_Name = new MiniWordColorText { Text = "MiniSofteware", FontColor = "#eb70AB" }, + Name = new MiniWordColorText { Text = "Jack", HighlightColor = "#eb70AB" }, + CreateDate = new MiniWordColorText + { + Text = new DateTime(2021, 01, 01).ToString() + , + HighlightColor = "#eb70AB", + FontColor = "#ffffff" + }, + VIP = true, + Points = 123, + APP = "Demo APP", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + } + + [Fact] + public async Task TestMultipleColorWordByWord() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestBasicFill.docx"); + var value = new + { + Company_Name = new MiniWordColorText { Text = "MiniSofteware", FontColor = "#eb70AB", }, + Name = new[] { + new MiniWordColorText { Text = "Ja", HighlightColor = "#eb70AB" }, + new MiniWordColorText { Text = "ck", HighlightColor = "#a56abe" } + }, + CreateDate = new MiniWordColorText + { + Text = new DateTime(2021, 01, 01).ToString(), + HighlightColor = "#eb70AB", + FontColor = "#ffffff", + }, + VIP = true, + Points = 123, + APP = "Demo APP", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + } + + + #region Model:TestIssue18.docx + public class Foo + { + public string title { get; set; } + public List managers { get; set; } + public List employees { get; set; } + } + public class User + { + public string name { get; set; } + public string department { get; set; } + } + #endregion + } +} diff --git a/tests/MiniWordTests/MiniWordTestAsync.cs b/tests/MiniWordTests/MiniWordTestAsync.cs new file mode 100644 index 0000000..d2dfa9a --- /dev/null +++ b/tests/MiniWordTests/MiniWordTestAsync.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using DocumentFormat.OpenXml.Office2010.ExcelAc; +using MiniSoftware; +using Xunit; + +namespace MiniWordTests +{ + public class MiniWordTestAsync + { + [Fact] + public async void TestForeachLoopInTablesAsync() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestForeachInTablesDemo.docx"); + var value = new Dictionary() + { + ["TripHs"] = new List> + { + new Dictionary + { + { "sDate", DateTime.Parse("2022-09-08 08:30:00") }, + { "eDate", DateTime.Parse("2022-09-08 15:00:00") }, + { "How", "Discussion requirement part1" }, + { + "Details", new List() + { + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Air"}, + {"Value", "Airplane"} + }, + Separator = " | " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Parking"}, + {"Value", "Car"} + }, + Separator = " / " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Hotel"}, + {"Value", "Room"} + }, + Separator = ", " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Food"}, + {"Value", "Plate"} + }, + Separator = "" + } + } + } + }, + new Dictionary + { + { "sDate", DateTime.Parse("2022-09-09 08:30:00") }, + { "eDate", DateTime.Parse("2022-09-09 17:00:00") }, + { "How", "Discussion requirement part2 and development" }, + { + "Details", new List() + { + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Air"}, + {"Value", "Airplane"} + }, + Separator = " | " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Parking"}, + {"Value", "Car"} + }, + Separator = " / " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Hotel"}, + {"Value", "Room"} + }, + Separator = ", " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Food"}, + {"Value", "Plate"} + }, + Separator = "" + } + } + } + } + } + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + //System.Diagnostics.Process.Start("explorer.exe", path); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Discussion requirement part2 and development", xml); + Assert.Contains(@"Discussion requirement part1", xml); + Assert.Contains( + "Air way to the Airplane | Parking way to the Car / Hotel way to the Room, Food way to the Plate", xml); + } + + [Fact] + public async void MiniWordIfStatement_FirstIfAsync() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestIfStatement.docx"); + var value = new Dictionary() + { + ["Name"] = new List(){ + new MiniWordHyperLink(){ + Url = "https://google.com", + Text = "測試連結22!!" + }, + new MiniWordHyperLink(){ + Url = "https://google1.com", + Text = "測試連結11!!" + } + }, + ["Company_Name"] = "MiniSofteware", + ["CreateDate"] = new DateTime(2021, 01, 01), + ["VIP"] = true, + ["Points"] = 123, + ["APP"] = "Demo APP", + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + //Console.WriteLine(path); + var docXml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains("First if chosen: MiniSofteware", docXml); + Assert.DoesNotContain("Second if chosen: MaxiSoftware", docXml); + Assert.Contains("Points are greater than 100", docXml); + Assert.Contains("CreateDate is not less than 2021", docXml); + Assert.DoesNotContain("CreateDate is not greater than 2021", docXml); + } + + [Fact] + public async void TestForeachLoopInTablesWithIfStatementAsync() + { + var path = PathHelper.GetTempFilePath(); + var templatePath = PathHelper.GetFile("TestForeachInTablesWithIfStatementDemo.docx"); + var value = new Dictionary() + { + ["TripHs"] = new List> + { + new Dictionary + { + { "sDate", DateTime.Parse("2022-09-08 08:30:00") }, + { "eDate", DateTime.Parse("2022-09-08 15:00:00") }, + { "How", "Discussion requirement part1" }, + { + "Details", new List() + { + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Air"}, + {"Value", "Airplane"} + }, + Separator = " | " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Parking"}, + {"Value", "Car"} + }, + Separator = " / " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Hotel"}, + {"Value", "Room"} + }, + Separator = ", " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Food"}, + {"Value", "Plate"} + }, + Separator = "" + } + } + } + }, + new Dictionary + { + { "sDate", DateTime.Parse("2022-09-09 08:30:00") }, + { "eDate", DateTime.Parse("2022-09-09 17:00:00") }, + { "How", "Discussion requirement part2 and development" }, + { + "Details", new List() + { + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Air"}, + {"Value", "Airplane"} + }, + Separator = " | " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Parking"}, + {"Value", "Car"} + }, + Separator = " / " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Hotel"}, + {"Value", "Room"} + }, + Separator = ", " + }, + new MiniWordForeach() + { + Value = new Dictionary() + { + {"Text", "Food"}, + {"Value", "Plate"} + }, + Separator = "" + } + } + } + } + } + }; + await MiniWord.SaveAsByTemplateAsync(path, templatePath, value); + //System.Diagnostics.Process.Start("explorer.exe", path); + var xml = Helpers.GetZipFileContent(path, "word/document.xml"); + Assert.Contains(@"Discussion requirement part2 and development", xml); + Assert.Contains(@"Discussion requirement part1", xml); + Assert.Contains("Air way to the Airplane | Hotel way to the Room", xml); + } + } +} \ No newline at end of file diff --git a/tests/MiniWordTests/MiniWordTests.csproj b/tests/MiniWordTests/MiniWordTests.csproj index 953e880..6b0cb5b 100644 --- a/tests/MiniWordTests/MiniWordTests.csproj +++ b/tests/MiniWordTests/MiniWordTests.csproj @@ -1,7 +1,7 @@ - net5.0; + net6.0; false