= сентябрь ";" оператор прерывает 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>
Ответы
Ответ 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 не интерпретировал последнюю строку правильно и проглотил последний разделитель, потому что это значение по умолчанию поведение.
Пожалуйста, поправьте меня, если я ошибаюсь