Export to DOC-File

108
19 декабря 2021, 15:20

Нашла один интересный вариант генерации файла про Word с расширением doc. (docx - не получается). Вдруг кому-то пригодится.

Брала код из разных источников и склеивала в один метод. Возможно этот способ будет кому то полезен. Для этого не нужно подключать какую то библиотеку. И вполне можно пользоваться для генерации doc-файла.

Базовая инфа взята с http://csharp-guide.blogspot.com/2012/06/aspnet-export-datatable-to-word.html. Но там нельзя просто взять и скопировать код.

Способ базируется на создание содержимого файла посредством оформления информации в формате HTML.

    public FileResult textGenDocx()
    {

        System.Text.StringBuilder sbDocBody = new System.Text.StringBuilder(); ;
        // Пример данных для отображения
        var dtSource = new System.Data.DataTable();
        dtSource.Columns.Add("One", typeof(string));
        dtSource.Columns.Add("Two", typeof(string));
        dtSource.Columns.Add("Three", typeof(string));
        dtSource.Columns.Add("Four", typeof(string));
        dtSource.Columns.Add("Five", typeof(string));
        dtSource.Rows.Add("1-", "2-", "3-", "4", "5");
        dtSource.Rows.Add("1-", "2-", "3-", "4", "5");
        dtSource.Rows.Add("1-", "2-", "3-", "4", "5");
        dtSource.Rows.Add("1-", "2-", "3-", "4", "5");
        dtSource.Rows.Add("1-", "2-", "3-", "4", "5");

        // Описываем стили CSS
        sbDocBody.Append("<style>");
        sbDocBody.Append(".Header { background-color:Navy; color:#ffffff; font-weight:bold;font-family:Verdana; font-size:12px;}");
        sbDocBody.Append(".SectionHeader { background-color:#8080aa; color:#ffffff; font-family:Verdana; font-size:12px;font-weight:bold;}");
        sbDocBody.Append(".Content { background-color:#ccccff; color:#000000; font-family:Verdana; font-size:12px;text-align:left}");
        sbDocBody.Append(".Label { background-color:#ccccee; color:#000000; font-family:Verdana; font-size:12px; text-align:right;}");
        sbDocBody.Append("</style>");
        // создаём StringBuilder и наполняем его содержимым HTML
        System.Text.StringBuilder sbContent = new System.Text.StringBuilder(); ;
        sbDocBody.Append("<br><table align=\"center\" cellpadding=1 cellspacing=0 style=\"background-color:#000000;\">");
        sbDocBody.Append("<tr><td width=\"500\">");
        sbDocBody.Append("<table width=\"100%\" cellpadding=1 cellspacing=2 style=\"background-color:#ffffff;\">");
        //
        if (dtSource.Rows.Count > 0)
        {
            sbDocBody.Append("<tr><td>");
            sbDocBody.Append("<table width=\"600\" cellpadding=\"0\" cellspacing=\"2\"><tr><td>");
            //                
            sbDocBody.Append("<tr><td width=\"25\"> </td></tr>");
            sbDocBody.Append("<tr>");
            sbDocBody.Append("<td> </td>");
            for (int i = 0; i < dtSource.Columns.Count; i++)
            {
                sbDocBody.Append("<td class=\"Header\" width=\"120\">" + dtSource.Columns[i].ToString().Replace(".", "<br>") + "</td>");
            }
            sbDocBody.Append("</tr>");
            //
            for (int i = 0; i < dtSource.Rows.Count; i++)
            {
                sbDocBody.Append("<tr>");
                sbDocBody.Append("<td> </td>");
                for (int j = 0; j < dtSource.Columns.Count; j++)
                {
                    sbDocBody.Append("<td class=\"Content\">" + dtSource.Rows[i][j].ToString() + "</td>");
                }
                sbDocBody.Append("</tr>");
            }
            sbDocBody.Append("</table>");
            sbDocBody.Append("</td></tr></table>");
            sbDocBody.Append("</td></tr></table>");

            string img = "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGRSURBVDhP7ZTbT8IwFMb9/5+NQcbAS/AWNb74JLcNWEBAxehQY0KmqBg1Kmxr1908ugJrtwiJvpj45cvSnp7z2+nWbc7/Jf1dECLe09B+0R1MPBpiNRPo8d0+vUFj37/adCGk6SDDcsOUwNAaXR4pHkQcT3sm5z3UucNw5Sjg675FU0eKAQEltjjss1tMs0eKAUEvkHqioZxqbzS9lbq/1XRh3NYYFjTbf5s8rBgQtAM1e8d2RvHC3m45HAs8ZsWArh7wgUrSihs1xDkQJAdVE5Bu+cULd7mKhNIwXSHpqhP1ZoM5B2DYYFBOQTr2snU7VSGJkjmfG8BArNpRZxQexG+teOmIFZIqW4KMF/JDuMI0aognCwNR0vfbWO3FPexsjYhlC5ySsSChZNEIppwTBT0Bt5EQpLU05kxS0E4L2sFjCzKkonAkCC6WjM+lr+nuEQlqA1FQvsOAOEMxbIoLrteZw01BA+QtwfuSzdnd6DKfLgWBgJVTrVXFFCTje6/VzMMucdnfyQT0Q/2Dpsn3PwD01EWc2A2jCQAAAABJRU5ErkJggg==\" alt=\"\">";
            sbDocBody.Append("<br>");
            sbDocBody.Append(img);
            string fileName = "ConvertedFile.doc";
            var ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sbDocBody.ToString()));
            var format = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
            return File(ms, format, fileName);
        }


        return null;
    }

Если надо использовать Net Framework, то последние три строчки будут заменены на:

             HttpContext.Current.Response.Clear();
             HttpContext.Current.Response.Buffer = true;
             HttpContext.Current.Response.AppendHeader("Content-Type", "application/msword");
             HttpContext.Current.Response.AppendHeader("Content-disposition", "attachment; filename="+fileName);
             HttpContext.Current.Response.Write(sbDocBody.ToString());
             HttpContext.Current.Response.End();

Такой способ конечно подходит не для всех видов сложности документов. Но для простых - это удобно и просто. Это моя субъективная точка зрения. Возможно кто то может посоветует вариант поудобнее.

Answer 1

Если все же вариант использования сторонних библиотек не отвергается, то создать docx-файл по шаблону можно с помощью TemplateEngine.Docx:
https://github.com/UNIT6-open/TemplateEngine.Docx
По ссылке есть подробная инструкция со скриншотами и примерами кода, но в общих чертах:

  1. Создаете docx шаблон с нужным вам дизайном
  2. Размечаете его с помощью Элементов управления содержимым (панель Разработчик в ленте Word)
  3. С помощью понятного API, используя имя такого элемента, заполняете текст внутри него Вашими данными.

Ваш пример мог бы выглядеть так:

            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
            var table = new TableContent("Table name");
            var headerCol1 = new FieldContent("Col1 Header", dtSource.Columns[0].ToString());
            var headerCol2 = new FieldContent("Col2 Header", dtSource.Columns[1].ToString());
            var headerCol3 = new FieldContent("Col3 Header", dtSource.Columns[2].ToString());
            var headerCol4 = new FieldContent("Col4 Header", dtSource.Columns[3].ToString());
            var headerCol5 = new FieldContent("Col5 Header", dtSource.Columns[4].ToString());

            for (int i = 0; i < dtSource.Rows.Count; i++)
            {
                table.AddRow(new FieldContent("Col1 value", dtSource.Rows[i][0].ToString()),
                             new FieldContent("Col2 value", dtSource.Rows[i][1].ToString()),
                             new FieldContent("Col3 value", dtSource.Rows[i][2].ToString()),
                             new FieldContent("Col4 value", dtSource.Rows[i][3].ToString()),
                             new FieldContent("Col5 value", dtSource.Rows[i][4].ToString()));
            }
            var valuesToFill = new Content(table, headerCol1, headerCol2, headerCol3, headerCol4, headerCol5);
            using (var outputDocument = new TemplateProcessor("OutputDocument.docx")
                .SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            }
READ ALSO
PHP. Сортировка в строке [дубликат]

PHP. Сортировка в строке [дубликат]

Есть строка со словами $words = "animal,people,cats,mack,apple,juice,mouse,marvel,keyboard,beer,drug,gun"; Слова разделены запятыми, в конце точка

102
Регулярное выражение просмотр вперёд

Регулярное выражение просмотр вперёд

Можно ли одним регулярным выражением выделить валидную строку в группу, в которых одновременно true оба выражения:

75
Ввод двумерного массива в PHP

Ввод двумерного массива в PHP

мне нужно вводить данные с поля textarea в двумерный массивВот моя форма:

196
Как обновлять контент в реальном времени?

Как обновлять контент в реальном времени?

Как обновлять информацию на странице в реальном времениНапример есть страница которая выводит записи пользователей из базы данных, простая...

156