首页 > 解决方案 > Excel 文件中 UTF-8 中的无效字节序列

问题描述

(Ruby 2.5)我有一种方法可以读取和解析通过 Alchemy CMS 上传的 csv 文件

def process_csv(csv_file, current_user_id, original_filename)
    lock_importer

    errors           = []
    index            = 0
    string_converter = lambda { |field| field.strip }
    total            = CSV.foreach(csv_file, headers: true).count
    csv_string = csv_file.read.encode!("UTF-8", "iso-8859-1", invalid: :replace)

    CSV.parse(csv_string, headers: true, header_converters: :symbol, skip_blanks: true, converters: [string_converter] ) do |row|
    # do other stuff
end

但是当我尝试上传一个 csv 文件,该文件的列(名称)和包含特殊字符的字符串时,我会收到Invalid Byte Sequence in UTF-8错误消息。我正在尝试测试 value N'öt Réal Stô'rë

我尝试了一些在网上找到的解决方案,但没有运气 - 有什么建议吗?

标签: ruby-on-railsencodingalchemy-cmsruby-2.5

解决方案


不清楚你csv_file是什么。我猜它是一个文件对象。

有时我从 Excel 获取 csv 作为 UTF-16。所以让我们尝试一个例子:

我有一个以 UTF-16BE 存储的 csv 文件,内容如下:

line;comment;UmlautÄ
1;Das ist UTF-16 BE;Ä
2;öüäÖÄÜ;Ä

如果我执行以下代码:

require 'csv'
def process_csv(csv_file)
    csv_string = csv_file.read#.encode!("UTF-8", "iso-8859-1", invalid: :replace)
    CSV.parse(csv_string, headers: true, skip_blanks: true, col_sep: ';') do |row|
      p row # do other stuff
    end
end

process_csv(File.open('example_utf16BE.txt'))

然后我也得到一个Invalid byte sequence in UTF-8-error。

如果我使用

process_csv(File.open('example_utf16BE.txt', 'rb', encoding: 'BOM|utf-16BE'))

然后一切正常。

所以我猜,你得到一个编码错误的文件对象,而代码csv_file.read.encode!("UTF-8", "iso-8859-1", invalid: :replace)是修复这个问题的代码部分。

你可以做什么:

添加到您的代码:

    p csv_file
    p csv_file.external_encoding

你应该得到

#<File:example_utf16BE.txt>
#<Encoding:UTF-16BE>

现在检查文件(在我的示例中:example_utf16BE.txt确实具有第二行的编码。

如果没有,请尝试调整文件对象的创建。如果这是不可能的,那么您可以csv_file.set_encoding 'utf-8'在阅读内容之前尝试使用更改编码。


推荐阅读