OTRS generated CSV and Unicode issue

It’s a while for now that we have problems with OTRS generated CSV files and Unicode. We are conducting an OTRS implementation in a Persian (Farsi) context. OTRS’s Stats (reports) module can generate CSV as output. There is 2 problems here. First, delimiter character used is Semicolon (;) not Comma (,) and second, because of our Unicode environment, CSV file format is UTF8. Following screenshot shows such a CSV file opened directly in MS Excel 2007, all of fields is just located in one column and Persian (Farsi) text are showed incorrectly as some meaningless characters:

A CSV file opened directly in MS Excel 2007

 

While searching for the solution in OTRS mailing lists, I found a good and very simple solution. Resolving the issue is possible by importing (not opening directly) the CSV with some considerations. All necessary steps are illustrated in the following.

1. Select “Get External Data, From Text” from Data menu and select desired CSV file:

Menu: Data->From Text->Get External Data From Text

 

2. A wizard opens. In the first step select “65001 : Unicode (UTF-8)” as “File Origin” and click “Next”:

Use

 

3. In the second step select “Semicolon” instead of “Comma” and click “Next”:

Select

 

4. In the 3rd step of wizard click “Finish” and in the “Import Data” window click “OK”. After this you will see your correct data in correct cell (each field in a separate column) and correct language (Persian text not garbage one) in MS Excel 2007:

Our CSV showed and interpreted in corrected way

 

Please consider that all of these instructions are applicable in MS Excel 2003 too.

‫قالب فایل CSV و یونیکد

CSV CSV یا همان Comma Seperated Values یک قالب فایل معروف و خیلی قدیمی (از حدود ۴۵ سال پیش!) است که در محیط‌ها و نرم افزارهای بسیار مختلفی مورد استفاده قرار می‌گیرد. در این قالب هر رکورد از اطلاعات در یک سطر فایل ذخیره می‌شود. و در هر سطر هم فیلدها به وسیله کاراکتر کاما «,» از هم جدا می‌شوند.

برای CSV هیچ استاندارد واحدی وجود ندارد. حتی RFC 4180 هم به صورت Informational ارائه شده است یعنی استاندارد واحدی را مشخص نکرده و صرفا قالبی که در بیشتر پیاده‌سازی‌ها مورد استفاده قرار گرفته را معرفی می‌کند. این یعنی اینکه CSV که از اکسل می‌گیرید لزوما با CSV که ممکن است از Gmail Contacts یا MySQL بگیرید یکی نخواهد بود. مثلا در یکی از header استفاده شده و در دیگری نه و یا مقدار فیلدها در یکی با double qution محصور شده و در دیگری نه. بدترین قسمت این ماجرا این است که در بیشتر پیاده سازی هیچ اهمیتی به Enocding داده نشده و فرض همه به ASCII بودن فایل است و بدتر از این از آنجا که به نظر می‌رسد CSV از Byte Order استفاده نمی‌کند (پاراگراف بعدی را ببینید) در نتیجه فایل آن حتما باید تک بایتی باشد مثل ASCII و UTF-8 و باز هم در نتیجه نمی‌توان از قالب‌های ۲ بایتی (یعنی هر کاراکتر در ۲ بایت ذخیره شود) مثل فایل‌های متنی یونیکد ویندوز در آن استفاده کرد. البته در حال تک بایتی هم Encoding را خود استفاده کننده باید بفهمد و نوع Encoding مورد استفاده از هیچ جای یک فایل CSV قابل استخراج نیست. در بعضی جاهای خاص مثل وقتی که قرار است فایل CSV به عنوان یک MIME TYPE به اسم text/csv رد و بدل شود یک header به نام charset هست که می‌توان Encoding را در آن معرفی نمود. فراموش نشود که این header خارج از خود فایل CSV قرار دارد.

در بعضی حالات به نظر می‌رسد که CSV از Byte Order استفاده می‌کند یعنی مثل فایل‌های متنی داخل ویندوز می‌شود یک یا چند بایت خاص را به منظور تعیین Encoding مورد استفاده در ابتدای فایل قرار داد و  سپس هر کاراکتر را با توجه به Encoding انتخابی ۱ یا ۲ بایت در نظر گرفت. البته در یکی دو آزمایش معلوم شد که خیلی برنامه‌ها از جمله Excel 2007 با فایل‌های متنی ۲ بایتی (ذخیره هر کاراکتر در ۲ بایت) مشکل دارند و این روش خیلی قابل اطمینان نیست.

نظر نگارنده این است که هر فایل CSV به صورت یک فایل متنی خالص تک بایتی بدون Byte Order ذخیره شده ولی برای ذخیره مقادیر یونیکد آنها را به قالب UTF-8 در آورده و در جای فیلدها ذخیره شود. برای خواندن این CSV هم همه فیلدها از UTF-8 به متن معمولی decode شود. به جای UTF-8 از هر روش دیگری هم که کاراکترهای یونیکد را به رشته‌ای از کاراکترهای تک بایت تبدیل می‌کنند هم می‌شود استفاده کرد. مثلا مثل این روش در صفحات HTML که کاراکتر «ن» فارسی با کد «#1606;» نمایش داده می‌شود. فقط باید دقت شود که استفاده کننده فایل CSV هم از روش Encoding مورد استفاده ما با خبر باشد.

 

منابع: