Сохранение в csv с фиксированной шириной столбца

Автор McAaron, 24 июня 2022, 22:52

0 Пользователи и 1 гость просматривают эту тему.

McAaron

Есть файл .ods, фрагмент которого во вложении. Его нужно вывести в формат для scanf(), чтобы далее с ним работать.
При сохранении в .csv с "фиксированной шириной столбца" колонки слипаются -- результат "save as" во вложении.
Можно, конечно, вставить пустые столбцы между ними, но условие обработки -- использовать, как пришло, не меняя в процессе ничего -- в перспективе предполагается запуск оффиса в headles режиме из скрипта. Офис ванильный.

И еще -- нет выравнивания по десятичной точке.  Ни в кальке, ни на выходе в csv.

Что посоветуете?

Версия: 6.4.7.2
ID сборки: 639b8ac485750d5696d7590a72ef1b496725cfb5
Потоков ЦП: 12; ОС: Linux 5.18; Отрисовка ИП: по умолчанию; VCL: gtk3;
Локаль: en-US (ru_RU.UTF-8); Язык интерфейса: ru-RU
Calc: threaded




economist

Архитектурно проще всего будет пять строк на python с pandas и либой-ровнялкой по десятичным точкам. Читаем ods, сохраняем csv.

Плюс pandas в том что можно решить любую проблему с форматом, вычислениями итп. И метода быстрее - не существует.
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

mikekaganski

Вы пишете:

Цитата: McAaron от 24 июня 2022, 22:52в перспективе предполагается запуск оффиса в headles режиме из скрипта

и при этом обсуждаете опции экспорта из UI. Зачем?
Для UI документация указывает, что ширина фиксированных столбцов зависит от ширины столбцов на листе. При этом, естественно, возникает магия преобразования ширины столбца Calc, выраженной (внутри) в твипах, в ширину в символах неизвестного шрифта (фиксированной ширины). Но поскольку это операция для GUI, такое упрощение принято допустимым (если пользователю не понравится результат, он изменит ширины столбцов и попробует снова).

А для использования в скрипте есть опции фильтра для командной строки, где поле 5 для фиксированной ширины задаётся как пары "позиция начала/формат". Задайте там нужные позиции начала, чтобы "не слипалось".
С уважением,
Михаил Каганский

mikekaganski

Цитата: McAaron от 24 июня 2022, 22:52нет выравнивания по десятичной точке

Это делается комбинацией числового формата, где для непечатаемых позиций используется не #, а ?, и использованием моноширинного шрифта. Тогда для чисел можно указать выравнивание по правой стороне, нужное число десятичных знаков, и получить выровненный по десятичному разделителю столбец. Естественно, если Вы правильно используете десятичный разделитель (в приложенном Вами ODS все "числа" - строки).
С уважением,
Михаил Каганский

economist

Пример для Python + Pandas:

import pandas, tabulate
df = pandas.read_excel('тм-data.ods')
with open('тм-data.csv', 'w') as f:
    f.write(tabulate.tabulate(df, headers=df.columns, showindex=True, tablefmt='simple'))

Рисунок вложен.
Форматирование строк можно произвести и кодом, и сторонними либами, как в этом примере.
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

mikekaganski

#5
Цитата: economist от 27 июня 2022, 12:56Пример для Python + Pandas:

@economist: я правильно понимаю (смотря на скриншот), что Pandas игнорирует тип данных в документе, и будет портить любой текст, состоящий из числовых символов (превращая идентификатор "0123e5" в 1.23e+7)?
С уважением,
Михаил Каганский

economist

Потенциально в форматах Excel/Calc и PDF лежат самые "грязные" данные. Такие всегда лучше считывать с параметром dtype='str', не полагаясь на автоопределение типов, и чистить уже после загрузки, кодом:

df = pd.read_excel('data.xlsx', dtype='str')
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

sokol92

Цитата: economist от 27 июня 2022, 10:45Плюс pandas в том что можно решить любую проблему с форматом, вычислениями итп. И метода быстрее - не существует.
На Basic можно тоже весьма эффективно экспортировать диапазон ячеек в текстовый файл сколь угодно сложного формата:
1. Получаем массив Basic c помощью метода getDataArray исходного диапазона ячеек.
2. Распределяем массив строк той же размерности (aDest).
3. Присваиваем значения элементам массива aDest.
4. Выводим Join(aDest, sNewLine) в текстовый файл. sNewline - символ(ы) перевода строк (специфичны для операционной системы).

Несколько десятков тысяч строк должны выводиться за секунды.
Владимир.

McAaron

Цитата: mikekaganski от 27 июня 2022, 11:22
Вы пишете:
Цитата: McAaron от 24 июня 2022, 22:52в перспективе предполагается запуск оффиса в headles режиме из скрипта
и при этом обсуждаете опции экспорта из UI. Зачем?
Затем, что прежде чем headles, нужно таки увидеть, что собой представляет вообще файл и можно ли его вывести в .csv без потери данных.

Что касается ссылки на "CSV Filter parameters", то это тот еще квест. Однако результат "remains the same" -- колонки слипаются.
$ libreoffice6.4 --convert-to "csv:Text - txt - csv (StarCalc):FIX,34,76,1,0/2/1/1/2/1/3/2/4/1/5/1" test.ods
Warning: failed to read path from javaldx
convert /home/user/testdata/test.ods -> /home/user/testdata/test.csv using filter : Text - txt - csv (StarCalc):FIX,34,76,1,0/2/1/1/2/1
$ head -3 test.csv
Время                 Номер   Значение             Время                  Номер   Значение         
31.01.2022 0:29:56.0007021    0.017                31.01.2022 11*20*23.8217995    -39.317           
31.01.2022 0:29:56.0007022    -0.047               31.01.2022 11*20*23.8217996    4.982       
     

Относительно формата строка второго и третьего столбца, то кальк именно так, ничего не спрашивая, импортировал .xlsx. Сам же .xlsx генерируется какой-то неведомой программой неведомо кем написанной и поменять ее выхлоп нет никакой возможности -- имеем "as is".
Что касается форматирования данных как "text", то второй столбец в число форматируется, а третий никак -- формат как бы становится числом, но остается прижатым влево и не распознается, как число.
Как этот столбец сформатировать в число? Что посоветуете?



mikekaganski

#9
Цитата: McAaron от 28 июня 2022, 14:28результат "remains the same" -- колонки слипаются.
$ libreoffice6.4 --convert-to "csv:Text - txt - csv (StarCalc):FIX,34,76,1,0/2/1/1/2/1/3/2/4/1/5/1" test.ods

Во-первых, я должен извиниться: я не проверил, что токен 5 действительно не применяется к экспорту, только к импорту - и соответственно, результирующую ширину столбцов невозможно задать из командной строки.

Правда, "для истории", идея была указывать позиции в символах - не 0/2/1/1/2/1/3/2/4/1/5/1, а что-то вроде 0/2/30/1/60/1/90/2/120/1/150/1.

tdf#149759 и tdf#149760

Что касается типа данных в ячейках - то тут всё определено в XLSX, и если генератор пишет всё строками, то ничего тут поделать из командной строки нельзя. Можно делать макросами или управлением из внешнего скрипта через UNO - открытием, использованием Text to Columns, возможно изменением ширины столбцов и экспортом ...

Я согласен с @economist, что в данном случае самый правильный вариант - pandas + tabulate (чтобы не писать это всё вручную), с указанием формата столбцов в параметрах импорта и экспорта (если нужно).
С уважением,
Михаил Каганский