Подтвердить что ты не робот

= сентябрь ";" оператор прерывает utf8 BOM в CSV файле, который генерируется XSL

В настоящее время я разрабатываю экспорт CSV с XSLT. И CSV файл будет использоваться% 99 процентов с Excel в моем случае, поэтому я должен рассмотреть поведение Excel.

Моя первая проблема - немецкие специальные персонажи в csv. Даже тот факт, что CSV-кодировка является UTF8, Excel не может правильно открыть CSV файл с UTF8. Специальные символы получают странные символы. Я нашел решение этой проблемы. Я добавил 3 дополнительных байта ( EF BB BF - a.k.a Заголовок спецификации) начало байтов содержимого. Потому что спецификация UTF8 - это способ сказать, что "эй чувак, это UTF8, откройте его правильно" в Excel. Проблема решена!

И моя вторая проблема была о разделителе. Разделитель по умолчанию может быть запятой или точкой с запятой в зависимости от региона. Я думаю, что это точка с запятой в Германии и запятая в Великобритании. Поэтому, чтобы предотвратить эту проблему, мне пришлось добавить строку ниже:

<xsl:text>sep=;</xsl:text>

или

<xsl:text>sep=,</xsl:text>

(Этот разделитель не был реализован как жестко запрограммированный)

Но моя проблема, которую я не могу найти, заключается в том, что если вы добавите "sep =;" или "sep =", начало файла, в то время как CSV файл генерируется с помощью UT8-BOM, спецификация не помогает показывать специальные символы правильно! И я уверен, что байты спецификации всегда находятся в начале массива байтов. Этот снимок экрана сделан из MS Excel в Mac OS X:

enter image description here

Первые 3 символа принадлежат заголовку спецификации.

У вас когда-нибудь была такая проблема или у вас есть какие-то предложения? Спасибо.

Edit:

Я использую печатные экраны.

а. С помощью спецификации и <xsl:text>sep=;</xsl:text>

enter image description here

б. Просто с BOM

enter image description here

Код Java:

// Write the bytes
ServletOutputStream out = resp.getOutputStream();
if(contentType.toString().equals("CSV")) {
  // The additional bytes in below is prefix indicates that the content is in UTF-8.
  out.write(239);
  out.write(187);
  out.write(191);
} 
out.write(bytes); // Content bytes, in this case XSL

Код XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes" />

    <xsl:template match="/">
    <xsl:text>sep=;</xsl:text>
    <table>
        ...
        </table>
</xsl:template>
4b9b3361

Ответ 1

Вы правы, в Excel 2007 нет способа заставить его правильно загружать как кодировку, так и seperator в разных локалях, когда кто-то дважды щелкает файл CSV.

Похоже, когда вы указываете sep = после спецификации, он забывает, что спецификация сообщила ему, что это UTF-8.

Вы должны указать спецификацию, потому что в определенных локалях Excel не обнаруживает разделителя. Например, на датском языке разделитель по умолчанию:;. Если вы выводите вкладку или разделенный запятой текст, то он не обнаруживает сеператор и в других местах, если вы разделите его на пол-двоеточия, он не загружается. Вы можете проверить это, изменив формат локалей в настройках окон - excel, затем выбирает это.

Из этого вопроса: Можно ли принудительно Excel распознавать файлы CSV UTF-8 автоматически?

и ответы, кажется, единственный способ использовать кодировку UTF16 le с спецификацией.

Обратите внимание, что согласно http://wiki.scn.sap.com/wiki/display/ABAP/CSV+tests+of+encoding+and+column+separator?original_fqdn=wiki.sdn.sap.com кажется, что если вы используете utf16-le с разделителями вкладок, то он работает.

Я задавался вопросом, читает ли excel sep =; а затем повторно вызывает метод для получения CSV-текста и теряет спецификацию - я попытался дать неправильный текст, и я не могу найти никакой работы, которая говорит excel, чтобы взять как sep, так и кодировку.

Ответ 2

Это результат моего тестирования с помощью Excel 2013.

Если вы застряли в UTF-8, есть временное решение, которое состоит из данных BOM + + sep =;

Вход (написанный с кодировкой UTF8)

\ufeffSome;Header;Columns Wîth;Fàncÿ;Stûff sep=;

Выход |Some|Header|Columns| |Wîth|Fàncÿ |Stûff | |sep=| | |

Проблема с решением заключается в том, что, хотя Excel правильно интерпретирует sep=;, он отображает sep= (да, он проглатывает ;) в первом столбце последней строки.

Однако, если вы можете записать файл как UTF16-LE, то есть реальное решение. Используйте разделитель \t без указания sep, и Excel будет играть в мяч.

Вход (написанный с кодировкой UTF16-LE)

\ufeffSome;Header;Columns Wîth;Fàncÿ;Stûff

Выход |Some|Header|Columns| |Wîth|Fàncÿ |Stûff |

Ответ 3

Я не могу писать комментарии, но я бы хотел обратиться к решению @Pier-Luc Gendreau. Хотя его можно открыть в Европейском Excel (который по умолчанию использует ; как разделитель) и имеет полную поддержку utf-16LE, по-видимому, невозможно использовать эту технику при указании sep=,.

Проблема с решением заключается в том, что Excel интерпретирует sep =; правильно отображает sep = (да, он проглатывает;) в первом столбце последней строки.

Для меня это не сработало, если я указал разделитель, который не был по умолчанию (; в моем случае), поэтому я полагаю, что Excel не интерпретировал последнюю строку правильно и проглотил последний разделитель, потому что это значение по умолчанию поведение.

Пожалуйста, поправьте меня, если я ошибаюсь