{"id":19099940,"url":"https://github.com/mini-software/MiniWord","last_synced_at":"2025-04-18T17:32:19.435Z","repository":{"id":59324702,"uuid":"535342676","full_name":"mini-software/MiniWord","owner":"mini-software","description":".NET Word(docx) exporting template engine without COM+ \u0026 interop (support Linux and Mac)","archived":false,"fork":false,"pushed_at":"2025-02-04T08:34:17.000Z","size":1136,"stargazers_count":670,"open_issues_count":44,"forks_count":86,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-18T04:57:50.317Z","etag":null,"topics":["csharp","dotnet","office","word"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mini-software.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://miniexcel.github.io"]}},"created_at":"2022-09-11T15:37:27.000Z","updated_at":"2025-04-17T12:27:42.000Z","dependencies_parsed_at":"2024-02-22T03:29:19.788Z","dependency_job_id":"cd73a80f-f513-4eab-95b3-d6100f7ee652","html_url":"https://github.com/mini-software/MiniWord","commit_stats":{"total_commits":74,"total_committers":6,"mean_commits":"12.333333333333334","dds":0.2702702702702703,"last_synced_commit":"9351082046d229f40bf6e9e73fdb8e3eca46b780"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mini-software%2FMiniWord","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mini-software%2FMiniWord/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mini-software%2FMiniWord/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mini-software%2FMiniWord/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mini-software","download_url":"https://codeload.github.com/mini-software/MiniWord/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249522303,"owners_count":21285492,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","office","word"],"created_at":"2024-11-09T03:52:23.970Z","updated_at":"2025-04-18T17:32:19.136Z","avatar_url":"https://github.com/mini-software.png","language":"C#","readme":"\u003cdiv align=\"center\"\u003e\n\u003cp\u003e\u003ca href=\"https://www.nuget.org/packages/MiniWord\"\u003e\u003cimg src=\"https://img.shields.io/nuget/v/MiniWord.svg\" alt=\"NuGet\"\u003e\u003c/a\u003e  \u003ca href=\"https://www.nuget.org/packages/MiniWord\"\u003e\u003cimg src=\"https://img.shields.io/nuget/dt/MiniWord.svg\" alt=\"\"\u003e\u003c/a\u003e  \n\u003ca href=\"https://github.com/mini-software/MiniWord\" rel=\"nofollow\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/mini-software/MiniWord?logo=github\" alt=\"GitHub stars\"\u003e\u003c/a\u003e \n\u003ca href=\"https://www.nuget.org/packages/MiniWord\"\u003e\u003cimg src=\"https://img.shields.io/badge/.NET-%3E%3D%204.5-red.svg\" alt=\"version\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\u003c/div\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\u003cp\u003e\u003cstrong\u003e\u003ca href=\"README.md\"\u003eEnglish\u003c/a\u003e | \u003ca href=\"README.zh-CN.md\"\u003e简体中文\u003c/a\u003e | \u003ca href=\"README.zh-Hant.md\"\u003e繁體中文\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e\n\u003c/div\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n Your \u003ca href=\"https://github.com/mini-software/MiniWord\"\u003eStar\u003c/a\u003e and \u003ca href=\"https://miniexcel.github.io\"\u003edotnate\u003c/a\u003e can make MiniWord better\n\u003c/div\u003e\n\n---\n\n## Introduction\n\nMiniWord is an easy and effective .NET Word Template library.\n\n![image](https://user-images.githubusercontent.com/12729184/190835307-6cd87982-b5f3-4a79-9682-bdd1cc02a4ea.png)\n\n\n\n## Getting Started\n\n### Installation \n\n- nuget link : https://www.nuget.org/packages/MiniWord\n\n### Quick Start\n\nTemplate follow \"WHAT you see is what you get\" design，and the template tag styles are completely preserved.\n\n```csharp\nvar value = new Dictionary\u003cstring, object\u003e(){[\"title\"] = \"Hello MiniWord\"};\nMiniSoftware.MiniWord.SaveAsByTemplate(outputPath, templatePath, value);\n```\n\n![image](https://user-images.githubusercontent.com/12729184/190875707-6c5639ab-9518-4dc1-85d8-81e20af465e8.png)\n\n### Input, Output\n\n- Input support file path, byte[]\n- Output support file path, byte[], stream\n\n```csharp\nSaveAsByTemplate(string path, string templatePath, Dictionary\u003cstring, object\u003e value)\nSaveAsByTemplate(string path, byte[] templateBytes, Dictionary\u003cstring, object\u003e value)\nSaveAsByTemplate(this Stream stream, string templatePath, Dictionary\u003cstring, object\u003e value)\nSaveAsByTemplate(this Stream stream, byte[] templateBytes, Dictionary\u003cstring, object\u003e value)\n```\n\n\n\n## Tags\n\nMiniWord template format string like Vue, React `{{tag}}`，users only need to make sure tag and value parameter key same then system will replace them automatically.\n\n### Text\n\n```csharp\n{{tag}}\n```\n\n##### Example\n\n```csharp\nvar value = new Dictionary\u003cstring, object\u003e()\n{\n    [\"Name\"] = \"Jack\",\n    [\"Department\"] = \"IT Department\",\n    [\"Purpose\"] = \"Shanghai site needs a new system to control HR system.\",\n    [\"StartDate\"] = DateTime.Parse(\"2022-09-07 08:30:00\"),\n    [\"EndDate\"] = DateTime.Parse(\"2022-09-15 15:30:00\"),\n    [\"Approved\"] = true,\n    [\"Total_Amount\"] = 123456,\n};\nMiniWord.SaveAsByTemplate(path, templatePath, value);\n```\n\n##### Template\n\n![image](https://user-images.githubusercontent.com/12729184/190834360-39b4b799-d523-4b7e-9331-047a61fd5eb9.png)\n\n##### Result\n\n![image](https://user-images.githubusercontent.com/12729184/190834455-ba065211-0f9d-41d1-9b7a-5d9e96ac2eff.png)\n\n### Image\n\nValue type is `MiniWordPicture` \n\n##### Example\n\n```csharp\nvar value = new Dictionary\u003cstring, object\u003e()\n{\n    [\"Logo\"] = new MiniWordPicture() { Path= PathHelper.GetFile(\"DemoLogo.png\"), Width= 180, Height= 180 }\n};\nMiniWord.SaveAsByTemplate(path, templatePath, value);\n```\n\n\n\n##### Template\n\n![image](https://user-images.githubusercontent.com/12729184/190647953-6f9da393-e666-4658-a56d-b3a7f13c0ea1.png)\n\n##### Result\n\n![image](https://user-images.githubusercontent.com/12729184/190648179-30258d82-723d-4266-b711-43f132d1842d.png)\n\n### List\n\ntag value is `string[]` or `IList\u003cstring\u003e` type\n\n##### Example\n\n```csharp\nvar value = new Dictionary\u003cstring, object\u003e()\n{\n    [\"managers\"] = new[] { \"Jack\" ,\"Alan\"},\n    [\"employees\"] = new[] { \"Mike\" ,\"Henry\"},\n};\nMiniWord.SaveAsByTemplate(path, templatePath, value);\n```\n\nTemplate\n\n![image](https://user-images.githubusercontent.com/12729184/190645513-230c54f3-d38f-47af-b844-0c8c1eff2f52.png)\n\n##### Result\n\n![image](https://user-images.githubusercontent.com/12729184/190645704-1f6405e9-71e3-45b9-aa99-2ba52e5e1519.png)\n\n### Table\n\nTag value is `IEmerable\u003cDictionary\u003cstring,object\u003e\u003e` type\n\n##### Example\n\n```csharp\nvar value = new Dictionary\u003cstring, object\u003e()\n{\n    [\"TripHs\"] = new List\u003cDictionary\u003cstring, object\u003e\u003e\n    {\n        new Dictionary\u003cstring, object\u003e\n        {\n            { \"sDate\",DateTime.Parse(\"2022-09-08 08:30:00\")},\n            { \"eDate\",DateTime.Parse(\"2022-09-08 15:00:00\")},\n            { \"How\",\"Discussion requirement part1\"},\n            { \"Photo\",new MiniWordPicture() { Path = PathHelper.GetFile(\"DemoExpenseMeeting02.png\"), Width = 160, Height = 90 }},\n        },\n        new Dictionary\u003cstring, object\u003e\n        {\n            { \"sDate\",DateTime.Parse(\"2022-09-09 08:30:00\")},\n            { \"eDate\",DateTime.Parse(\"2022-09-09 17:00:00\")},\n            { \"How\",\"Discussion requirement part2 and development\"},\n            { \"Photo\",new MiniWordPicture() { Path = PathHelper.GetFile(\"DemoExpenseMeeting01.png\"), Width = 160, Height = 90 }},\n        },\n    }\n};\nMiniWord.SaveAsByTemplate(path, templatePath, value);\n```\n\n##### Template\n\n![image](https://user-images.githubusercontent.com/12729184/190843632-05bb6459-f1c1-4bdc-a79b-54889afdfeea.png)\n\n\n##### Result\n\n![image](https://user-images.githubusercontent.com/12729184/190843663-c00baf16-21f2-4579-9d08-996a2c8c549b.png)\n\n### List inside list\n\nTag value is `IEnumerable\u003cMiniWordForeach\u003e` type. Adding `{{foreach` and `endforeach}}` tags to template is required.\n\n##### Example\n\n```csharp\nvar value = new Dictionary\u003cstring, object\u003e()\n{\n    [\"TripHs\"] = new List\u003cDictionary\u003cstring, object\u003e\u003e\n    {\n        new Dictionary\u003cstring, object\u003e\n        {\n            { \"sDate\", DateTime.Parse(\"2022-09-08 08:30:00\") },\n            { \"eDate\", DateTime.Parse(\"2022-09-08 15:00:00\") },\n            { \"How\", \"Discussion requirement part1\" },\n            {\n                \"Details\", new List\u003cMiniWordForeach\u003e()\n                {\n                    new MiniWordForeach()\n                    {\n                        Value = new Dictionary\u003cstring, object\u003e()\n                        {\n                            {\"Text\", \"Air\"},\n                            {\"Value\", \"Airplane\"}\n                        },\n                        Separator = \" | \"\n                    },\n                    new MiniWordForeach()\n                    {\n                        Value = new Dictionary\u003cstring, object\u003e()\n                        {\n                            {\"Text\", \"Parking\"},\n                            {\"Value\", \"Car\"}\n                        },\n                        Separator = \" / \"\n                    }\n                }\n            }\n        }\n    }\n};\nMiniWord.SaveAsByTemplate(path, templatePath, value);\n```\n\n##### Template\n\n![before_foreach](https://user-images.githubusercontent.com/38832863/220123955-063c9345-3998-4fd7-982c-8d1e3b48bbf8.PNG)\n\n\u003cimg width=\"755\" alt=\"Screenshot 2023-08-08 at 17 59 37\" src=\"https://github.com/mini-software/MiniWord/assets/38832863/7811bf53-48cf-4fa4-85d7-d98663feb119\"\u003e\n\n##### Result\n\n![after_foreach](https://user-images.githubusercontent.com/38832863/220123960-913a7140-2fa2-415e-bb3e-456e04167382.PNG)\n\n\u003cimg width=\"755\" alt=\"Screenshot 2023-08-08 at 18 00 15\" src=\"https://github.com/mini-software/MiniWord/assets/38832863/9e1afcf7-64b1-441c-8488-9ea2bd3114a1\"\u003e\n\n### If statement inside template\n\nFor multip paragraph, use @if and @endif tags.\nFor single paragraph and inside foreach, use `{{if` and `endif}}` tags to template is required.\n\n##### Example\n\n```csharp\nvar value = new Dictionary\u003cstring, object\u003e()\n{\n    [\"Name\"] = new List\u003cMiniWordHyperLink\u003e(){\n        new MiniWordHyperLink(){\n            Url = \"https://google.com\",\n            Text = \"測試連結22!!\"\n        },\n        new MiniWordHyperLink(){\n            Url = \"https://google1.com\",\n            Text = \"測試連結11!!\"\n        }\n    },\n    [\"Company_Name\"] = \"MiniSofteware\",\n    [\"CreateDate\"] = new DateTime(2021, 01, 01),\n    [\"VIP\"] = true,\n    [\"Points\"] = 123,\n    [\"APP\"] = \"Demo APP\",\n};\nMiniWord.SaveAsByTemplate(path, templatePath, value);\n```\n\n##### Template For Multi Paragraph\n\n![before_if](https://user-images.githubusercontent.com/38832863/220125429-7dd6ce94-35c6-478e-8903-064f9cf9361a.PNG)\n\n##### Result Of Multi Paragraph\n\n![after_if](https://user-images.githubusercontent.com/38832863/220125435-72ea24b4-2412-45de-961a-ad4b2134417b.PNG)\n\n##### Template For Single Paragraph\n\n\u003cimg width=\"931\" alt=\"Screenshot 2023-08-08 at 17 55 46\" src=\"https://github.com/mini-software/MiniWord/assets/38832863/2adea468-a9c1-422f-a270-167086bc4ba3\"\u003e\n\n##### Result Of Single Paragraph\n\n\u003cimg width=\"536\" alt=\"Screenshot 2023-08-08 at 17 56 47\" src=\"https://github.com/mini-software/MiniWord/assets/38832863/01f71c0f-eee0-4189-8510-abe063126514\"\u003e\n\n### ColorText\n\n##### Example\n\n```csharp\nvar value = new\n{\n    Company_Name = new MiniWordColorText { Text = \"MiniSofteware\", FontColor = \"#eb70AB\", },\n    Name = new[] {\n        new MiniWordColorText { Text = \"Ja\", HighlightColor = \"#eb70AB\" },\n        new MiniWordColorText { Text = \"ck\", HighlightColor = \"#a56abe\" }\n    },\n    CreateDate = new MiniWordColorText\n    {\n        Text = new DateTime(2021, 01, 01).ToString(),\n        HighlightColor = \"#eb70AB\",\n        FontColor = \"#ffffff\",\n    },\n    VIP = true,\n    Points = 123,\n    APP = \"Demo APP\",\n};\nMiniWord.SaveAsByTemplate(path, templatePath, value);\n```\n\n\n## Other\n\n### POCO or dynamic parameter\n\nv0.5.0 support POCO or dynamic parameter\n\n```csharp\nvar value = new { title = \"Hello MiniWord\" };\nMiniWord.SaveAsByTemplate(outputPath, templatePath, value);\n```\n\n### FontColor and HighlightColor\n```csharp\nvar value = new\n{\n    Company_Name = new MiniWordColorText { Text = \"MiniSofteware\", FontColor = \"#eb70AB\" },\n    Name = new MiniWordColorText { Text = \"Jack\", HighlightColor = \"#eb70AB\" },\n    CreateDate = new MiniWordColorText { Text = new DateTime(2021, 01, 01).ToString(), HighlightColor = \"#eb70AB\", FontColor = \"#ffffff\" },\n    VIP = true,\n    Points = 123,\n    APP = \"Demo APP\",\n};\n```\n\n### HyperLink\n\nIf value type is `MiniWordHyperLink` system will replace template string by hyperlink.\n\n* Url： HyperLink URI target path\n* Text：Description \n\n```csharp\nvar value = new \n{\n    [\"Name\"] = new MiniWordHyperLink(){\n        Url = \"https://google.com\",\n        Text = \"Test Link!!\"\n    },\n    [\"Company_Name\"] = \"MiniSofteware\",\n    [\"CreateDate\"] = new DateTime(2021, 01, 01),\n    [\"VIP\"] = true,\n    [\"Points\"] = 123,\n    [\"APP\"] = \"Demo APP\",\n};\nMiniWord.SaveAsByTemplate(path, templatePath, value);\n```\n\n\n\n## Examples\n\n\n\n#### ASP.NET Core 3.1 API Export\n\n```cs\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Net;\nusing MiniSoftware;\n\npublic class Program\n{\n    public static void Main(string[] args) =\u003e CreateHostBuilder(args).Build().Run();\n\n    public static IHostBuilder CreateHostBuilder(string[] args) =\u003e Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =\u003e webBuilder.UseStartup\u003cStartup\u003e());\n}\n\npublic class Startup\n{\n    public void ConfigureServices(IServiceCollection services) =\u003e services.AddMvc();\n    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n    {\n        app.UseStaticFiles();\n        app.UseRouting();\n        app.UseEndpoints(endpoints =\u003e\n        {\n            endpoints.MapControllerRoute(\n                name: \"default\",\n                pattern: \"{controller=api}/{action=Index}/{id?}\");\n        });\n    }\n}\n\npublic class ApiController : Controller\n{\n    public IActionResult Index()\n    {\n        return new ContentResult\n        {\n            ContentType = \"text/html\",\n            StatusCode = (int)HttpStatusCode.OK,\n            Content = @\"\u003chtml\u003e\u003cbody\u003e\n\u003ca href='api/DownloadWordFromTemplatePath'\u003eDownloadWordFromTemplatePath\u003c/a\u003e\u003cbr\u003e\n\u003ca href='api/DownloadWordFromTemplateBytes'\u003eDownloadWordFromTemplateBytes\u003c/a\u003e\u003cbr\u003e\n\u003c/body\u003e\u003c/html\u003e\"\n        };\n    }\n\n    static Dictionary\u003cstring, object\u003e defaultValue = new Dictionary\u003cstring, object\u003e()\n    {\n        [\"title\"] = \"FooCompany\",\n        [\"managers\"] = new List\u003cDictionary\u003cstring, object\u003e\u003e {\n            new Dictionary\u003cstring, object\u003e{{\"name\",\"Jack\"},{ \"department\", \"HR\" } },\n            new Dictionary\u003cstring, object\u003e {{ \"name\", \"Loan\"},{ \"department\", \"IT\" } }\n        },\n        [\"employees\"] = new List\u003cDictionary\u003cstring, object\u003e\u003e {\n            new Dictionary\u003cstring, object\u003e{{ \"name\", \"Wade\" },{ \"department\", \"HR\" } },\n            new Dictionary\u003cstring, object\u003e {{ \"name\", \"Felix\" },{ \"department\", \"HR\" } },\n            new Dictionary\u003cstring, object\u003e{{ \"name\", \"Eric\" },{ \"department\", \"IT\" } },\n            new Dictionary\u003cstring, object\u003e {{ \"name\", \"Keaton\" },{ \"department\", \"IT\" } }\n        }\n    };\n\n    public IActionResult DownloadWordFromTemplatePath()\n    {\n        string templatePath = \"TestTemplateComplex.docx\";\n\n        Dictionary\u003cstring, object\u003e value = defaultValue;\n\n        MemoryStream memoryStream = new MemoryStream();\n        MiniWord.SaveAsByTemplate(memoryStream, templatePath, value);\n        memoryStream.Seek(0, SeekOrigin.Begin);\n        return new FileStreamResult(memoryStream, \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\")\n        {\n            FileDownloadName = \"demo.docx\"\n        };\n    }\n\n    private static Dictionary\u003cstring, Byte[]\u003e TemplateBytesCache = new Dictionary\u003cstring, byte[]\u003e();\n\n    static ApiController()\n    {\n        string templatePath = \"TestTemplateComplex.docx\";\n        byte[] bytes = System.IO.File.ReadAllBytes(templatePath);\n        TemplateBytesCache.Add(templatePath, bytes);\n    }\n\n    public IActionResult DownloadWordFromTemplateBytes()\n    {\n        byte[] bytes = TemplateBytesCache[\"TestTemplateComplex.docx\"];\n\n        Dictionary\u003cstring, object\u003e value = defaultValue;\n\n        MemoryStream memoryStream = new MemoryStream();\n        MiniWord.SaveAsByTemplate(memoryStream, bytes, value);\n        memoryStream.Seek(0, SeekOrigin.Begin);\n        return new FileStreamResult(memoryStream, \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\")\n        {\n            FileDownloadName = \"demo.docx\"\n        };\n    }\n}\n```\n\n\n\n\n\n\n## Support : [Donate Link](https://miniexcel.github.io/)","funding_links":["https://miniexcel.github.io"],"categories":["dotnet"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmini-software%2FMiniWord","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmini-software%2FMiniWord","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmini-software%2FMiniWord/lists"}