Импорт текстов в базу из массива файлов doc и docx

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Импорт текстов в базу из массива файлов doc и docx

Сообщение jsa » 25.07.2024 06:30:54

Здравствуйте.
Имеется большое количество файлов (протоколы врачей) в формате docx и doc
Структура внутри простая, ненужная картинка эмблема, заголовок и текст, размер 1-2 страницы
Сохраняли давно поэтому есть и doc (Word 2003-XP) и docx(Word 2007+)
Можно использововать MS Office или LibreOffice

Задача вгрузить тексты в базу данных. Минимум получается 2 поля путь+имя файла и сам текст со всеми переносами, пробелами, табами (нумерации и спец разметки там нет)

Покопался тут и погуглил, все темы в основном старые и мало подробностей.
Получается алгоритм такой
1. Перебор в цикле и ли рекурсией папок подпапок с файлами.
2. Запуск/открытие Офиса с подачей в него очередного файла.
3. Получение текста из активного документа.
4. сохранение в базу (разбор и исправление огрех, вопрос не стоит, это второй этап)

пункт 3. не смог найти как реализовать.
Подскажите пожалуйста, кто знает.
jsa
постоялец
 
Сообщения: 282
Зарегистрирован: 28.11.2017 13:46:04

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение Снег Север » 25.07.2024 08:49:46

В Делфи есть платный компонент для чтения вордовских файлов, а в лазаре скорее всего придется сначала делать конвейер для конвертации docx и doc в odt через LibreOffice, а потом парсить этот odt, я этим не занимался. но встречал, что odt имеет структуру xml.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3046
Зарегистрирован: 27.11.2007 16:14:47

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение jsa » 25.07.2024 09:32:41

Снег Север писал(а):что odt имеет структуру xml.

Так и docx имеет структуру XML

Только не имеет смысл что-то во что-то конвертировать, если удастся подключиться к sWrite как к OLE объекту и тянуть тест оттуда.
jsa
постоялец
 
Сообщения: 282
Зарегистрирован: 28.11.2017 13:46:04

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение WAYFARER » 25.07.2024 09:44:05

jsa, docx - это xml в zip архиве. Парсить можно, но сложно ввиду сложной с структуры, с doc всё еще сложнее.
В одном из проектом пришли к простому, но эффективному решению. Документы (doc/docx) конвертируются в html с помощью LibreOffice (soffice --headless --convert-to html:HTML %filename%). Полученный html уже прекрасно парсится (для freepascal с помощью SaxHtml или FastHtmlParser, например)

jsa писал(а):Задача вгрузить тексты в базу данных. Минимум получается 2 поля путь+имя файла и сам текст со всеми переносами, пробелами, табами (нумерации и спец разметки там нет)

А в вашем случае, раз нет никакой сложной структуры типа таблиц вообще можно конвертировать в txt
Код: Выделить всё
soffice --headless --convert-to txt:Text %filename%

В результате как раз получите "сам текст со всеми переносами, пробелами, табами " который можно будет забирать в базу как есть.
Аватара пользователя
WAYFARER
энтузиаст
 
Сообщения: 537
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение jsa » 25.07.2024 09:47:07

Вот это поворот!!! Спасибо! погуглю попробую.

Добавлено спустя 1 минуту 13 секунд:
%filename% в случае примеров это входной или выходной файл?
Если входной то куда выход? и наоборот?
jsa
постоялец
 
Сообщения: 282
Зарегистрирован: 28.11.2017 13:46:04

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение sts » 25.07.2024 09:56:23

Код: Выделить всё
  function PrepareFile(FileName: string): string;
  const
    wdFormatText = 2;
   
    wdExportFormatPDF = 17;
    wdExportFormatXPS = 18;

    wdExportOptimizeForPrint = 0;
    wdExportOptimizeForOnScreen = 1;

    wdExportAllDocument = 0;
    wdExportCurrentPage = 2;
    wdExportFromTo = 3;
    wdExportSelection = 1;

    wdDoNotSaveChanges = 0;


  var
    WordApp: OleVariant;
    wd: OleVariant;
   
    procedure wdInit(UseActiveObject: Boolean);
    begin
      WordApp := Unassigned;
      if not UseActiveObject then
        WordApp := CreateOleObject('Word.Application')
      else
        try
          WordApp := GetActiveOleObject('Word.Application');
        except
          WordApp := CreateOleObject('Word.Application');
        end;
    end;
   
  begin

    wdInit(true);
    wd:= WordApp.Documents.Open(FileName);

    wd.Activate;

    result:= ChangeFileExt(FileName, '.txt');

//    wd.ExportAsFixedFormat(result, wdExportFormatPDF, false, wdExportOptimizeForPrint, wdExportAllDocument);
    wd.SaveAs(result, wdFormatText);
   
    wd.Close(wdDoNotSaveChanges);
  end;   


Добавлено спустя 1 минуту 30 секунд:
как то надо было в pdf сохранять
переделал код на текст, не проверял

Добавлено спустя 1 минуту 16 секунд:
+uses Variants, ComObj
sts
постоялец
 
Сообщения: 440
Зарегистрирован: 04.04.2008 12:15:44
Откуда: Тольятти

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение jsa » 25.07.2024 10:07:10

Спасибо, рассматривал уже имеющиеся примеры через Word.Application
но решил сначала тему с LibreOffice до изучать.

Работает!

Код: Выделить всё
"C:\Program Files\LibreOffice\program\soffice" --headless --convert-to txt:Text "D:\test\ПротоколТест.docx"

отрабатывает отлично и создает одноименный txt файл рядом.

Просмотрю или такой вариант или в HTML с разбором последующим.

Всем спасибо, особенно WAYFARER.
Да причинится тебе успех, удача и прочая сбыча мечт.
jsa
постоялец
 
Сообщения: 282
Зарегистрирован: 28.11.2017 13:46:04

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение WAYFARER » 25.07.2024 10:08:58

jsa писал(а):%filename% в случае примеров это входной или выходной файл?

Это входной. Выходной будет по тому же пути с тем же именем, но другим расширением. Если нужно положить выходной файл куда то отдельно то нужно использовать опцию --outdir
Аватара пользователя
WAYFARER
энтузиаст
 
Сообщения: 537
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение jsa » 30.07.2024 10:01:41

Набросал утилиту сделал конвертацию у себя на рабочем месте.
Перетащил на целевой комп, а там конвертация не работает.
в CMD запускаю

Код: Выделить всё
"C:\Program Files\LibreOffice\program\soffice" --headless --convert-to txt:TEXT "C:\tmp\123.docx"

получаю ошибку
Код: Выделить всё
convert C:\tmp\123.docx as a Writer document -> C:\tmp\123.txt using filter : TEXT
Error: Please verify input parameters... (SfxBaseModel::impl_store <file:///C:/tmp/123.txt> failed: 0x81a(Error Area:Io Class:Parameter Code:26) at C:/cygwin64/home/buildslave/source/libo-core/sfx2/source/doc/sfxbasemodel.cxx:3272 at C:/cygwin64/home/buildslave/source/libo-core/sfx2/source/doc/sfxbasemodel.cxx:1822)


Сколько ошибку не гуглил, не нашел ответа что с этим делать. Был вариант что прав нет на папку. но всё что могли выдали, и папки разные попробовали.

Сталкивались с таким?
jsa
постоялец
 
Сообщения: 282
Зарегистрирован: 28.11.2017 13:46:04

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение RRYTY » 30.07.2024 10:24:52

RRYTY
постоялец
 
Сообщения: 221
Зарегистрирован: 25.12.2021 10:00:32

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение jsa » 30.07.2024 11:31:57

RRYTY писал(а):Попробуйте

попробовал, ровно тоже самое.
jsa
постоялец
 
Сообщения: 282
Зарегистрирован: 28.11.2017 13:46:04

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение iskander » 30.07.2024 11:44:47

Емнип в винде до OO можно было достучаться через COM, что-нибудь вроде
Код: Выделить всё
function OoGetText(const aFileName: string; out aErr: string): TStringList;
var
  Manager: Variant;
  function CreateProp(const aName: string; const aValue: Variant): Variant;
  begin
    Result := Manager.Bridge_GetStruct('com.sun.star.beans.PropertyValue');
    Result.Name := aName;
    Result.Value := aValue;
  end;
var
  App, Params, Doc: Variant;
  Url: string;
begin
  Result := nil;
  try
    Manager := CreateOleObject('com.sun.star.ServiceManager');
  except
    on e: Exception do begin
      aErr := Format('%s: "%s"', [e.ClassName, e.Message]);
      exit;
    end;
  end;
  App := Manager.CreateInstance('com.sun.star.frame.Desktop');
  Url := 'file:///' + aFileName;
  Params := VarArrayOf([CreateProp('Hidden', True), CreateProp('ReadOnly', True)]);
  try
    Doc := App.LoadComponentFromUrl(Url, '_blank', 0, Params);
  except
    on e: Exception do begin
      aErr := Format('%s: "%s"', [e.ClassName, e.Message]);
      exit;
    end;
  end;
  Result := TStringList.Create;
  Result.Text := Doc.Text.&String;
end;

Может оказаться, что всё ещё актуально?
iskander
энтузиаст
 
Сообщения: 607
Зарегистрирован: 08.01.2012 18:43:34

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение RRYTY » 30.07.2024 12:19:03

jsa писал(а):ровно тоже самое


Значит, не пробовали. Портируемая версия не использует никаких cygwin. И исполняемый файл другой.
RRYTY
постоялец
 
Сообщения: 221
Зарегистрирован: 25.12.2021 10:00:32

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение jsa » 30.07.2024 12:59:30

convert_01.png


Добавлено спустя 8 минут 15 секунд:
RRYTY писал(а):И исполняемый файл другой.

Какой именно?
jsa
постоялец
 
Сообщения: 282
Зарегистрирован: 28.11.2017 13:46:04

Re: Импорт текстов в базу из массива файлов doc и docx

Сообщение RRYTY » 30.07.2024 14:10:47

quote="jsa"]Какой именно?[/quote]

Кто ж его знает. Но вот так сработало.
001.png
001.png (1.51 КБ) Просмотров: 17085


Ваш-то файл открывается в принципе?
RRYTY
постоялец
 
Сообщения: 221
Зарегистрирован: 25.12.2021 10:00:32

След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru