Оптимизация заполения таблицы в MS Word

408
16 января 2017, 18:28

Всем привет. У меня стоит задачка в заполнении таблицы в MS Word.
Пытаюсь сделать двумя способами:
В первом способе требуется ускорить процесс заполнения таблицы, занимает очень много времени на 1500 записей 15-20 минут.

Во втором способе проблема с получением вставленной таблицы.
Я ее пытаюсь получить из текущего Word.Range (Word.Range.Tables[1]), в который вставляю таблицу, но мне почему-то не возвращает мою таблицу. Пока только на одном компьютере, не знаю как исправить эту ситуацию. Вставка таблицы через HTML файл не лучший вариант, потому что потом нужно доставлять многострочный текст и картинки.

1) Заполняю таблицу очень просто.

Word.Table.AddRow();  
Word.Row[indexRow].Cell[indexColumn].Range.Text = "Требуемый текст"

2) Заполнение таблицы заключается в том, что я сначала создаю HTML файл с таблицой, потом вставляю этот файл в MS Word.

Word.Range.InsertFile("path.html")

Место куда вставляю определяю через закладку в шаблоне.

Word.ActiveDocument.Bookmarks["Table"].Range

Требуется совместимость с MS Word 2003 - 2013. Сторонние библиотеки использовать не могу, только стандартную Interop.Microsoft.Word.

Answer 1

Самое просто- это отказаться от тормознутого interop в пользу OpenXml.

В отличии от *.doc, который является бинарным форматом, *.docx- представляет собой контейнер с *.xml файлами(OpenXml формат), что позволяет работать с файлом используя сторонние библиотеки, например EPPlus.

После того, как вы сделали все необходимые операции вы можете через interop сохранить файл в более низкой версии(.doc) и это должно быть быстрее.

Это можно реализовать в качестве WCF-сервиса на котором будет стоять свежий офис.

Сервис будет манпипулировать данными в формате .docx, а возвращать .doc.

На мой взгляд, это самое быстрое решение.

Answer 2

Честно говоря, вообще первый раз использовал ActiveX. Да еще и для Microsoft Word'а. Просто хотелось посмотреть всеж быстродействие. В принципе, получилось. Записываем следующий код в файл test.js и выполняем:

var app = new ActiveXObject("Word.Application");
    app.Visible = true;
var doc = app.Documents.Add();
var range = doc.Paragraphs(doc.Paragraphs.Count).Range;
    range.Text = "1,data12,data13\n"+
                 "1,data22,data23\n"+
                 "1,data32,data33\n"+
                 "1,data22,data23\n"+
                 "1,data32,data33\n"+
                 "1,data22,data23\n"+
                 "1,data32,data33\n"+    // тут для теста
                 "1,data22,data23\n"+    // можно добавить
                 "1,data32,data33\n"+    // еще 3000
                 "1,data22,data23\n"+    // подобных строк
                 "1,data32,data33\n"+
                 "1,data22,data23\n"+
                 "1,data32,data33\n"+
                 "1,data22,data23\n"+
                 "1,data32,data33\n"+
                 "1,data22,data23\n"+
                 "1,data32,data33\n"+
                 "1,data22,data23\n"+
                 "1,data32,data33\n"+
                 "1,data22,data23\n"+
                 "1,data32,data33\n"+
                 "1,data22,data23\n"+
                 "1,data32,data33\n";
var table = range.ConvertToTable(",",1,3);
    table.Borders.Enable = 1;
    table.Columns(1).SetWidth(32,0);

Должен сформироваться документ с таблицей.

Извините, что на JavaScript'е - C# не знаю, впрочем, как и JavaScript тоже :). Но на С# и пробовать не на чем. Тем не менее, мой скрипт делал таблицу на 3000 строк в Microsoft Word около секунды-полторы. Я думаю, переделать на C# труда особого не составит.

Вариант с загрузкой HTML (JavaScript)

Получился вот такой вариант:

var app = new ActiveXObject("Word.Application");
    app.Visible = true;
var doc = app.Documents.Add();
var parag = doc.Paragraphs.Add();
    parag.Range.Font.Bold = true;
    parag.Range.Font.Color = 0xCF7214;
    parag.Range.Font.Size = 18;
    parag.Range.Text = "Это такой заголовок таблицы\n";
    parag = doc.Paragraphs.Add();
    range = doc.Paragraphs(doc.Paragraphs.Count).Range;
    range.InsertFile("C:\\temp\\table.html");
    parag = doc.Paragraphs.Add();
    parag.Range.Text = "Всего таблиц в документе: " + doc.Tables.Count;
var table = doc.Tables(1);
    table.Columns(1).Cells(1).Range.Text = "Заголовок-1";
    table.Columns(2).Cells(1).Range.Text = "Заголовок-2";
    table.Columns(3).Cells(1).Range.Text = "Заголовок-3";
    table.Columns(1).Cells(1).Range.Font.Bold = true;
    table.Columns(2).Cells(1).Range.Font.Bold = true;
    table.Columns(3).Cells(1).Range.Font.Bold = true;
    table.Columns(1).Cells(1).Range.ParagraphFormat.Alignment = 1;
    table.Columns(2).Cells(1).Range.ParagraphFormat.Alignment = 1;
    table.Columns(3).Cells(1).Range.ParagraphFormat.Alignment = 1;
    table.Borders.Enable = true;

Сам HTML- файл:

<html>
<body>
<table width="100%" cellspacing="0">
<tr><td valign="center">A</td><td valign="center">B</td><td valign="center">C</td></tr>
<tr><td><img src="file:///C:/Temp/!pic.png"></td><td>1</td><td>11</td></tr>
<tr><td><img src="file:///C:/Temp/!pic.png"></td><td>2</td><td>22</td></tr>
</table>
</body>
</html>

Результат:

READ ALSO
Ошибки: Cannot implicitly convert type &#39;string&#39; to &#39;int&#39; и Argument 1: cannot convert from &#39;int&#39; to &#39;string&#39;

Ошибки: Cannot implicitly convert type 'string' to 'int' и Argument 1: cannot convert from 'int' to 'string'

Пытаюсь написать парсерВроде сделал всё как в уроке

278
Не работает checkbox в DataGridView

Не работает checkbox в DataGridView

На грид добавлена колонка с типом чекбоксВсе выводится замечательно, но при нажатии на чекбокс он не отмечается

403
Убить процесс в C#

Убить процесс в C#

Я уже не знаюКак я только не пробовал убить процесс chrome

432
Десериализация json-строки в Словарь (Dictionary&lt;TKey, TValue&gt;)

Десериализация json-строки в Словарь (Dictionary<TKey, TValue>)

Есть JSON описанный вышеДля десериализации я использую Newtonsoft

337