|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
Привет. Сам я дельфист, пытаюсь бороться с одной фигней которая рождается где-то внутри питона которым занимается другой чел. Этот чел упирается в то что у него ошибок не может быть, исправляйте сами где хотите, на стороне получателя этого файла. Ситуация такая. Данные лежат в базе Firebird-2.5 Кодировка всей базы win1251. Приложение написанное на Delphi работает с базой без проблем. В базе есть блоб-поля содержащие описание товара, многострочный текст. Код: plsql 1. 2. 3. 4. 5.
Из этой базы скрипт на питоне вытягивает данные и сохраняет в файл xlsx. Проблема в том что в этом файле в ячейках с многострочным текстом появляется лишний символ переноса строки. Прикол в том что в самом Excel он не отображается, но при загрузке из этого файла в 1С он становится видимым и далее везде фигурирует как непонятный хвост текста. Внутри xlsx, файл sharedStrings.xml в котором хранятся строки, после форматирования, выглядит так Код: html 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
Видно что перевод строки тут есть, но так же, в конце каждой строки в многострочном поле торчат символы "_x000D_" На сколько я понял, в XML шаблон вида _x****_ используется для кодирования юникодных символов их кодом. Соответственно, _x000D_ это символ CR, но в Windows одиночный CR не является ни печатным ни управляющим символом, поэтому он и не отображается т.к. не печатный, ни приводит к переводу строки т.к. не является управляющим. В файле, после _x000D_ идет обычный перевод строки CR+LF (0D+0A) он и переводит строку. Excel такие вещи обходит, символов _x000D_ в ячейке не видно, а вот 1С при чтении этого файла отображает _x000D_ как часть строки. При этом перенос строки есть. Питонист говорит что делает свое черное дело таким кодом, и ошибок там никаких быть не может. Код: python 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31.
Отступы в коде - какие мне дали, при передаче через чат. Вопрос - откуда берется этот символ, нет ли каких-то известных граблей в питоне на эту тему? Гугление мне не помогло. Но я питон не знаю от слова "совсем". ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2021, 11:56 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
fraks Данные лежат в базе Firebird-2.5 fraks Вопрос - откуда берется этот символ Если вопрос исследовательский, то, видимо, есть смысл посмотреть содержимое полей, а далее по ситуации. Если же вопрос чисто практический, нужно избавиться от символа (или байта)... ну так и вырезать его перед использованием данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2021, 18:40 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
fraks, берётся из xls/xlsx файла - это перевод строки. заменяй вручную на то, что нужно. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2021, 18:51 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
vkle fraks Данные лежат в базе Firebird-2.5 fraks Вопрос - откуда берется этот символ Если вопрос исследовательский, то, видимо, есть смысл посмотреть содержимое полей, а далее по ситуации. Если же вопрос чисто практический, нужно избавиться от символа (или байта)... ну так и вырезать его перед использованием данных. В базе кодировка win1251, НЕ юникод, там обычный cr+lf. В файле xlsx перед тем самым cr+lf добавляется еще _x000D_ который портит всю малину. Я бы понял если бы он вставлялся ВМЕСТО cr+lf, но оно именно добавляется. Бороться с последствиями - достаточно неблагодарное занятие, тем более что это не полностью нам подконтрольно, и программисты 1С которые занимаются загрузкой данных из этого файла xlsx так и говорят - что вы в файл подсунули то мы и грузим. Сейчас у меня выбор - показать нашему питонисту, в кавычках, в каком месте он облажался, или переписать этот скрипт на Delphi. Я бы давно переписал, но у меня нет наработанного кода по работе с xlsx, есть только с xls. Конечно, это все можно решить, но это время. Если же есть реальная ошибка в питоньем коде - то достаточно эту ошибку убрать и на этом всё. Может быть имеет значение что питоний код выполняется на linux, проблема в том как преобразовывается перенос строки windows-unix. Может косяк в sqlalchemy или pandas, может быть нужно указать какие-то параметры по работе с переносом строк что бы получалось нужное, может быть проблема с драйвером firebird для питона. Вопрос у меня в том - баг это или фича. Если баг - исправляем, если фича - решаем как с этой фичей жить. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2021, 19:22 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
DHDD fraks, берётся из xls/xlsx файла - это перевод строки. заменяй вручную на то, что нужно. То что берется из файла - я так и написал. В исходных данных имеется обычный виндовый cr+lf Вопрос - зачем там вместо cr+lf оказывается _x000D_+cr+lf Причем если cr+lf это 2 символа, то _x000D_ это 7 символов. Еще раз - мне нужно не удалить этот _x000D_ из файла, а сделать так что бы он туда не попадал. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2021, 19:25 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
fraks Еще раз - мне нужно не удалить этот _x000D_ из файла, а сделать так что бы он туда не попадал. Для этого нужно, чтобы входной текст не содержал символа 0D - как показало беглое гугление, эксел для разделения строк в ячейке использует только символ 0A, но при этом маскирует обработку _x000D_ :) IMHO, удаление лучше делать в коде экспорта на питоне, чем в БД ... |
|||
:
Нравится:
Не нравится:
|
|||
28.04.2021, 21:56 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
x1ca4064 fraks Еще раз - мне нужно не удалить этот _x000D_ из файла, а сделать так что бы он туда не попадал. Для этого нужно, чтобы входной текст не содержал символа 0D - как показало беглое гугление, эксел для разделения строк в ячейке использует только символ 0A, но при этом маскирует обработку _x000D_ :) IMHO, удаление лучше делать в коде экспорта на питоне, чем в БД В БД, которая работает в кодировке win1251, совершенно легитимно находится обычный виндовый перевод строки, состоящий из двух символов CR+LF они же 0D 0A. Никто ни за каким надом не будет ломать работу основной программы, у которой все в порядке. Excel может быть и маскирует, но в файле имеется строка символов _x000D_ которые появились там еще до того как Excel коснулся этого файла. Как-то он разбирается с этой комбинацией. Но иной софт, в частности 1С, символы cr+lf понимают правильно, а символы _x000D_ воспринимают как текст. Если из файла символы _x000D_ удалить, оставив только обычный cr+lf, т.е. 0D 0A - то в Excel ничего не меняется, переводы строк остаются на месте. Еще раз - Excel как-то с ними разбирается, Excel молодец, но мне нужно что бы эти левые символы не писались в файл в питоне, т.к. далее с этим файлом работает совсем не Excel. Ладно бы, если какой-то питоний модуль в используемой цепочке вообще бы не умел работать с переводами строк, но он переводы строк видит и сует к ним лишнее. С какой целью он это делает и в каком месте? ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 03:48 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
fraks Ладно бы, если какой-то питоний модуль в используемой цепочке вообще бы не умел работать с переводами строк, но он переводы строк видит и сует к ним лишнее. С какой целью он это делает и в каком месте? Вероятно, формат требует, чтобы перевод строки был 0A, в целях "совместимости" эксел допускает наличие символа 0D и _x000D_, другие программы это могут не уметь. Если в ячейку эксела запихать символ 0D, эффект, скорее всего, будет таким же (не проверял), поэтому корректно работающий писатель в формат эксел добавляет это "заклинание". Я сам не спец по питону, но это можно исправлять, выполнив удаление символа 0D в DataFrame ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 04:36 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
x1ca4064 fraks Ладно бы, если какой-то питоний модуль в используемой цепочке вообще бы не умел работать с переводами строк, но он переводы строк видит и сует к ним лишнее. С какой целью он это делает и в каком месте? Вероятно, формат требует, чтобы перевод строки был 0A, в целях "совместимости" эксел допускает наличие символа 0D и _x000D_, другие программы это могут не уметь. Никто ничего не требует. Если сделать файл непосредственно в Excel то никаких _x000D_ он туда сам не добавляет, там обычный 0D 0A. И все прекрасно работает, как в Excel так и при чтении файла в 1С. Где-то унутрях питона кто-то начинает умничать и пихать в файл _x000D_ которого там не было и который там нафиг не нужен. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 04:53 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
fraks Если сделать файл непосредственно в Excel то никаких _x000D_ он туда сам не добавляет, там обычный 0D 0A. К сожалению, у меня нет современного экселя, но, что 2002 эксел, что ОпенОфис сохраняют многострочный текст с разделителем 0A. При вставке в ячейку символа 0D, он в этих пакетах сохраняется "как есть", т.е. без всяких "дополнений". У Вас есть возможность проверить на современном экселе, как сохраняется ячейка, в которую вставили символ 0D (и 0D0A)? Если есть, выложите файл. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 06:06 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
del ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 06:14 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
fraks, Вот дискуссия , чем-то напоминающая нашу. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 06:15 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
Еще идея появилась, на счет откуда берутся _x000D_ Поле stov.descr не текстовое, а блоб. При чтении в pandas.DataFrame его значение определяется как какой тип? Может быть, из-за типа, или из-за наличия непечатных символов cr+lf оно в датафрейме определяется как байтовое или еще какое, а потом, при выводе в excel оно приводится к текстовому типу, как из байтов, тогда и появляется этот _x000D_ Может быть, после загрузки данных, принудительно определить тип поля https://www.statology.org/pandas-to-string/ и тогда его не будет корежить при экспорте. * https://github.com/pandas-dev/pandas/blob/v0.24.2/pandas/io/excel.py#L953-L1195 Код: python 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32.
Текст самой pandas.compat.to_str найти не смог. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 07:01 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
x1ca4064 fraks, Вот дискуссия , чем-то напоминающая нашу. Спасибо. Именно оно. Человек так же искренне недоумевает от этой херни, как и я, а ему объясняют что в питоне никаких ошибок нет, так и должно быть :) ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 07:29 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
x1ca4064 fraks Если сделать файл непосредственно в Excel то никаких _x000D_ он туда сам не добавляет, там обычный 0D 0A. К сожалению, у меня нет современного экселя, но, что 2002 эксел, что ОпенОфис сохраняют многострочный текст с разделителем 0A. При вставке в ячейку символа 0D, он в этих пакетах сохраняется "как есть", т.е. без всяких "дополнений". У Вас есть возможность проверить на современном экселе, как сохраняется ячейка, в которую вставили символ 0D (и 0D0A)? Если есть, выложите файл. MS Office 2019 В ячейке A1 между A и B символы CR+LF В ячейке A2 между C и D символы LF ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 07:35 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
Сам файл ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 07:35 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
Как я понял, экспорт данных из pandas в Excel делается при помощи библиотеки libxlsxwriter. Автор этой библиотеки, jmcnamara, стоит на такой позиции: 1. перевод строки может быть только LF(0A) 2. варианты CR+LF абсолютно нелегитимны 3. если ты думаешь что это не так - смотри п.1 Исходя из этого, автор в своей библиотеке делает следующее: если встречается CR (0D) то он его экранирует в формате _x000D_ который как бы соответствует чему-то, и Excel это хавает, но кроме него никто этим не заморачивается т.к. сам Excel такой херни не делает. При этом есть еще и ошибка. Экранированный _x000D_ дописывается, но исходный CR (0D) так же остается, в неэкранированном виде, получается масло масляное, зачем было экранировать если неэкранированное осталось. Есть ли такой постулат что строки в python имеют право быть только с переносом LF(0A) - я не в курсе. Если такое есть - то jmcnamara имеет какие-то основания на свою позицию, но он этого не озвучивает. Опять же, если есть, то пребразование CR+LF-> LF должно выполняться при любом чтении данных в строки, а это видимо не так. Тесты, которые делает jmcnamara, с очень высокой степенью вероятности выполняются на linux а не на windows, (судя по использванию утилиты $ xxd test-25/xl/sharedStrings.xml) Программа на Си, откомпиленная под linux кажись использует под понятием \n не то что программа под windows. это сразу же делает тесты неознозначными и не применимыми ко всем случаем, в частности к windows. Автор другой библиотеки по работе с тем же самым, проблему исправил. https://github.com/CoreOffice/CoreXLSX/issues/83 Что остается делать. При использовании пандаса для экспорта данных в Excel видимо придется пойти на поводу у jmcnamara и преобразовать данные внутри DataFrame, удалив оттуда CR(0D). Надеюсь тогда не будет появляться его клон в виде _x000D_. Идиотские советы некоторых, https://stackoverflow.com/questions/36167807/access-newline-becoming-x000d типа сделай так и поломай исходные данные, идут лесом. Код: plsql 1.
Спасибо за участие. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 08:16 |
|
Python - символы _x000D_ при экспорте в xlsx
|
|||
---|---|---|---|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
В обоих местах "0d0a" ... |
|||
:
Нравится:
Не нравится:
|
|||
29.04.2021, 09:06 |
|
|
start [/forum/topic.php?fid=23&msg=40067068&tid=1459481]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
37ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
47ms |
get tp. blocked users: |
1ms |
others: | 10ms |
total: | 138ms |
0 / 0 |