В общем, есть Word-документы формата *.doc. В этих Word-документах есть чередования таблиц и текста.
Мне нужно идти сверху вниз документа и если я встречаю простой текст, то делаю одно действие, если таблицу, то что-то другое.
С Word-ом никогда не работал. Можно ли какой-нибудь простой пример работы с Word'ом?
Пока нашел, что к таблицам я могу достучаться через свойства Tables
, но это не интересно, так как чередование таблиц и текста мне важно.
Вроде, костыльно и методом тыка нарисовал такого монстра:
for (var parIdx = 1; parIdx <= doc.Paragraphs.Count; parIdx++)
{
Paragraph paragraph = doc.Paragraphs[parIdx];
if (paragraph.Range.Tables.Count > 0)//Параграф является таблицей, если таблиц>0
{
foreach (Table table in paragraph.Range.Tables)
{
parIdx += table.Range.Paragraphs.Count;//делаем смещение на кол-во параграфов, которые задействованы в таблице
for (int i = 1; i <= table.Rows.Count; i++)
{
var res = String.Empty;
Row row = table.Rows[i];
for (var j = 1; j <= row.Cells.Count; j++)
{
var cell = row.Cells[j].Range.Text;
res += "|" + String.Join("", cell.Where(chr => !Char.IsControl(chr)));
}
}
}
}
else
{
var text = String.Join("", paragraph.Range.Text.Where(chr => !Char.IsControl(chr)));
Console.WriteLine($"TEXT:{text}");
}
}
Если у кого-то есть более красивый вариант, то предлагайте.
Приведу пример, как я парсил doc на js. На с# не переписывал. Писал давно.
var fs = new ActiveXObject("Scripting.FileSystemObject");
function doc2txt(afile){
var z,d,f, dd, content;
content = "";
afile = afile.toLowerCase();
if (afile.indexOf('.')<0) return;
if (afile.charAt(0)=='~') return;
if (afile.indexOf('.doc')>0) { /* Расшифровка DOC файла */
//var f = fs.OpenTextFile("курс валют_01.02.11.doc");
f = fs.OpenTextFile(afile,1,0,-1); // открываем файл как юникод
d = f.Read(0xA00 / 2); // Пропустить заголовок
while (1) {
try { d = f.Read(256); } catch (e) { return content;}; // читаем блок
dd = d.substring(0,1);
dd = escape(dd);
dd = dd.replace("%u","");
try {
dd = eval("0x" + dd); // получаем значение первого двойного слова
} catch(e) { dd = 0;};
// Проверяем первое двойное слово на "мусор" и служебные
if (dd == 0x14AA) return content;
if (dd > 7000) return content;
if ((dd & 0xFF00) == 0x600) continue;
if ((dd & 0xFF00) == 0x800) continue;
if ((dd & 0xFF00) == 0x900) continue;
if ((dd & 0xFF00) == 0xA00) continue;
if ((dd & 0xFF00) == 0xC00) continue;
if ((dd & 0xFF00) == 0xE00) continue;
// далее преобразовуем "нечитабельный" текст
d = areplace(d,unescape("%00"),"");
d = areplace(d,unescape("%08"),"|");// Преобразование для таблицы \t в |
d = escape(d);
d = areplace(d,"%07","|"); // Преобразование для таблицы
d = areplace(d,"%uFFFF","");
d = areplace(d,escape(","),","); d = areplace(d,escape("."),".");
d = areplace(d,"%0A",""); // убираю \r
d = unescape(d);
//content += "hdr="+ dd+ ";" + d;
content += d; // добавляем в копилку обработаный текст.
// WScript.Echo(dd + " = " + d);
}
}
}
function areplace(a,b,c){
var i;
while (1){
i = a.length;
a = a.replace(b,c);
if (a.length==i) break;
};
return a;
};
После обработки, в таблицах разделитель \t
, так же есть разделитель линий. Служебную информацию не видно, данные отдаёт как понятный текст.
Код работает под виндой. В кратце - doc-файл представляет собой biff-файл, т.е. небольшую "файловую" систему. 512-байт (0xA00) идет заголовок. Далее идут секции по 4096 байт. Один из "файлов" в системе содержит поток doc-документа, который разбит на секции по 512 байт. Если идет читабельный текст - то он внутри секции 512 байт. Текст хранится в юникоде.
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Добрый день, подскажитеЕсть запрос ajax, он работает, данные в БД передаются, ответ приходит, если в БД есть хоть 1 запись, то полученные данные...
Ситуация следующаяЕсть какой-то класс A, при создании которого в конструкторе на определенный узел DOM должен быть навешен обработчик
Как вызвать функцию объекта, если имя объекта и имя функции хранятся в переменной?