ruby-on-rails - 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ë
。
我尝试了一些在网上找到的解决方案,但没有运气 - 有什么建议吗?
解决方案
不清楚你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'
在阅读内容之前尝试使用更改编码。
推荐阅读
- linux - 使用 ideviceinstaller 侧载 ipa
- java - 显示时间而不转换为本地时区
- android - 使用 Expo 构建的应用程序中不存在/未加载数据库
- angular - 订阅的组件无法访问 observable 的响应
- visual-studio-code - VScode 图标窗口不会立即更新
- matlab - 使用 SNPS VCS 工具在 System verilog 中使用 MATLAB 脚本
- javascript - CSS延迟将元素的可见性从“可见”更改为“隐藏”
- angular - 从 ionic 5.4.16 中的 http 响应获取标头参数
- javascript - 如何为按钮列表赋予随机背景颜色?
- reactjs - 链接不重定向到 React 中的页面