Итак, у нас есть это веб-приложение, в котором мы поддерживаем данные UTF8. Ура UTF8. И мы можем без проблем экспортировать предоставленные пользователем данные в CSV - на тот момент они все еще в UTF8. Проблема заключается в том, что когда вы открываете типичный CSV-файл UTF8 в Excel, он читает его как текст в кодировке ANSII и, соответственно, пытается прочитать двухбайтовые символы, такие как ø и ü, как два отдельных символа, и в итоге вы терпите неудачу.
Итак, я немного покопался (у ребят из Interval есть интересный пост об этом здесь), и есть некоторые ограниченные, но до смешного раздражающие варианты. Среди них:
Похоже, что несмотря ни на что, я, вероятно, захочу продолжить предлагать простой старый CSV-файл для людей, которые все равно не используют его для Excel, и отдельный вариант загрузки для Excel.
Какой самый простой способ создать этот файл Just-For-Excel, который будет правильно поддерживать UTF8, мои дорогие переполнители стека? Если этот простейший вариант поддерживает только последнюю версию Excel, это все еще интересно.
Я делаю это в стеке Rails, но любопытно, как .Net-ers и люди на любых фреймворках справляются с этим. Я сам работаю в нескольких разных средах, и это определенно проблема, которая возникнет снова.
Обновление 2010-10-22: Мы использовали гем Ruport в нашей системе учета рабочего времени Темп для обеспечения экспорта CSV, когда я впервые разместил этот вопрос. Один из моих коллег, Эрик Холленсби, собрал быстрый фильтр для Ruport, чтобы предоставить нам фактические выходные данные Excel XSL, и я решил поделиться этим здесь с любыми другими рубиновиками:
require 'rubygems'
require 'ruport'
require 'spreadsheet'
require 'stringio'
Spreadsheet.client_encoding = "UTF-8"
include Ruport::Data
class Ruport::Formatter::Excel < Ruport::Formatter
renders :excel, :for => Ruport::Controller::Table
def output
retval = StringIO.new
if options.workbook
book = options.workbook
else
book = Spreadsheet::Workbook.new
end
if options.worksheet_name
book_args = { :name => options.worksheet_name }
else
book_args = { }
end
sheet = book.create_worksheet(book_args)
offset = 0
if options.show_table_headers
sheet.row(0).default_format = Spreadsheet::Format.new(
options.format_options ||
{
:color => :blue,
:weight => :bold,
:size => 18
}
)
sheet.row(0).replace data.column_names
offset = 1
end
data.data.each_with_index do |row, i|
sheet.row(i+offset).replace row.attributes.map { |x| row.data[x] }
end
book.write retval
retval.seek(0)
return retval.read
end
end





Вы забываете создать источник данных OleDB и взаимодействие с Excel, но с ними тоже есть проблемы.
Я рекомендую вариант SpreadsheetML. Он работает довольно хорошо, скорее всего, на вашей платформе есть неплохие инструменты для создания файлов xml, и он полностью поддерживается еще в OfficeXP. Office2000 не поддерживается, но личный опыт показывает, что он работает ограниченно.
@Richard - из-за 2-го абзаца, который не полагается на oledb. Хотя из обновления, которое было опубликовано более полутора лет спустя, здесь должен быть ответ, указывающий на Руби Руперт.
Если вы создадите XML с кодировкой utf и сохраните его как .xls, он откроет даже эти двухбайтовые символы:
xml version = "1.0" encoding = "utf-8"
Я попытался просто сохранить XML-документ табличных данных с расширением .xls, а затем открыл его в Excel для Mac 2003, и он просто отключил его. И изрядное количество наших пользователей - люди Mac.
Я никогда не пробовал это с MAC, но он должен работать, XML - стандарт
У меня была такая же проблема с отправкой данных UTF8 в Excel. Мое решение:
Текущая версия кода Perl Spreadsheet :: WriteExcel cpan правильно записывает файлы Excel с использованием данных UTF8.
Итак, я написал плагин Rails, который а) открывает двусторонний канал к программе Perl б) отправляет данные по очереди в программу Perl. Я использую Yaml в качестве формата данных сообщения. (Стандартный Ruby yaml - это не UTF8, есть специальная версия ya2yaml) c) Программа perl создает файл Excel г) Когда программа Rails указывает (через сообщение yaml), что последняя строка была отправлена, программа perl создает файл excel и отправляет статус обратно программе rails.
Конечно, добавление Perl-программы к проекту rails посредством параллельного процесса и конвейера относится скорее к «инженерным», чем к «компьютерным наукам». (Он выполняет свою работу, но не изящно.) Но он работает хорошо и сэкономил мне несколько недель на перенос кода WriteExcel на Ruby. Также обратите внимание, что доступный в настоящее время порт WriteExcel на Ruby не поддерживает utf8.
Мой SW является неограниченно открытым исходным кодом, но я еще не успел его выпустить. Если вы хотите, чтобы он был в текущем состоянии, см. http://sandbox.kluger.com/write_excel_v.5.tar
Обратите внимание, что вы захотите создавать свои файлы Excel в фоновом процессе, а не в процессе контроллера Rails, так как это заблокирует другие клиенты браузера, когда вы усердно создаете файл Excel. Пользуюсь плагином DelayedJob, работает хорошо.
Надеюсь это поможет,
Ларри
Попробуйте OpenOffice Calc - он гораздо более дружелюбен к Unicode - как импорт, так и экспорт файлов CSV с кодировкой UTF-8.
Вопрос заключался в том, как экспортировать эти данные из веб-приложения таким образом, чтобы пользователи могли открывать их в Excel. Скорее всего, не сработает просто сказать всем своим клиентам, чтобы они использовали openoffice.
Честно говоря, плакат правильно утверждает, что OpenOffice более дружелюбен к юникоду, чем Excel. Я пришел сюда в поисках способа сделать это с помощью Excel, потому что больше не хочу использовать OpenOffice.
После нескольких часов борьбы с той же проблемой я нашел этот отличный пост на эту тему.
http://blog.plataformatec.com.br/2009/09/exporting-data-to-csv-and-excel-in-your-rails-app/ Цитировать :
So, these are the three rules for dealing with Excel-friendly-CSV:
- Use tabulations, not commas.
- Fields must NOT contain newlines.
- Use UTF-16 Little Endian to send the file to the user. And include a Little Endian BOM manually.
Однако, если вы используете рубин, ваша проблема решена: сначала у вас есть драгоценный камень FasterCSV
но в итоге я использовал жемчужину электронных таблиц, которая напрямую генерирует электронные таблицы Excel (у меня есть ограничение по ссылкам, просто таблица google + rubyforge) Блестяще!
Excel неправильно обрабатывает UTF-8. Вместо этого вы должны использовать кодовую страницу, которая соответствует вашим потребностям.
Response.ContentType = "text/plain";
// codepage: 28591, codepage name:iso-8859-1, codepage display name: Western European (ISO)
Response.ContentEncoding = System.Text.Encoding.GetEncoding(28591);
Кажется, у меня все работает нормально, если вы добавляете подпись / спецификацию UTF8 (EF BB BF).
Я обнаружил, что если вы установите кодировку кодировки веб-страницы на utf-8, а затем Response.Binary Запишите метку порядка байтов UTF-8 (0xEF 0xBB 0xBF) в верхней части файла csv, затем Excel 2007 (не уверен в другие версии) распознают его как utf-8 и правильно откроют.
Я разместил здесь код, который делает это - stackoverflow.com/a/9907364/150342
Обсуждение того, как это сделать, находится в stackoverflow.com/questions/4389005/…
Я наткнулся на этот пост в поисках ответа Ruby о том, почему Excel не может правильно загружать CSV с символами utf-8. После поиска и экспериментов это решение сработало для меня:
csv_content = CSV.generate(col_sep: "\t", headers: :first_row, encoding: 'utf-8') do |csv|
csv << ["header1", "header2"]
csv << ["content1", "content2"]
end
write_content = Iconv.conv("utf-16le", "utf-8", "\xEF\xBB\xBF")
write_content += Iconv.conv("utf-16le", "utf-8", csv_content)
File.open("listing.csv", 'wb') {|f| f.write(write_content) }
"Вы забываете ... OleDB ..." Шшш! Это среда unix, поэтому я бы хотел избежать такого рода Voodoo. Спасибо за чаевые!