?

Log in

No account? Create an account

Entries by category: it

Проверка кодировки, конвертация в UTF-8
necrosfodel
Итак, на данный момент удалось портировать код загрузчика xlsx-файлов с Go на Beego. Было добавлено определение кодировки с помощью charder и конвертация в случае необходимости в UTF-8 с помощью text/transform. На данный момент все, что эта фигня делает - инициализирует считывание файла по нажатию кнопки с помощью AJAX-запроса (этот код на javascript я не привожу), обрабатывает его на стороне сервера и выдает результат в консоль. Прямо скажем, не густо. Но это временно.
На данный момент главная задача - научиться создавать динамические модели на основе загружаемых файлов. Ни один питон с джангой такое не может, потому что там нет такой штуки, как interface{}. А interface{} может быть использован в качестве поля любого типа: int, string, bool и в принципе всего, что душе угодно. Поэтому, чисто теоретически, можно создать такую базовую модель, которая будет состоять из полей, содержащих такие интерфейсы. Единственным ограничением будет количество этих полей. Таким образом будет не принципиально, какой именно файл мы загружаем. Все связи с интерфейсом для него будут создаваться в момент загрузки (возможно, при загрузке необходимо будет указывать, какие поля являются чем - датами, описаниями событий и т.д.). Если так не получится, тогда придется более жестко привязывать загружаемые файлы к существующей модели, в которой будет некоторое количество полей каждого из типов. Тогда, естественно, порядок полей будет меняться.

package controllers

import (
    "github.com/astaxie/beego"
    "path/filepath"
    "github.com/tealeg/xlsx"
    "golang.org/x/text/transform"
    "golang.org/x/text/encoding/charmap"
    "strings"
    "io/ioutil"
    "github.com/saintfish/chardet"
)

type XLSXController struct {
    beego.Controller
}

type XLSXtoSQLController struct {
    beego.Controller
}

func (this *XLSXController) Get() {
    this.Data["Url"] = "127.0.0.1:8080"
    this.TplName = "xlsx.tpl"
}

func (this *XLSXtoSQLController) XLSXtoSQL() {
    tbl := make(map[int]map[int]string)
    excelFileName, _ := filepath.Abs("C:/workspace/gopath/src/realhistory/3G_support_0104.xlsx")
    xlFile, err := xlsx.OpenFile(excelFileName)
    if err != nil {
        beego.Info("panic")
    }
    for _, sheet := range xlFile.Sheets {
        for row_idx, row := range sheet.Rows {
            //Инициализация вложенных карт - издержки языка Go
            if _, ok := tbl[row_idx]; !ok {
                tbl[row_idx] = make(map[int]string)
            }
            for col_idx, cell := range row.Cells {
                value, _ := cell.String()
                //Определяем кодировку
                detector := chardet.NewTextDetector()
                result, err := detector.DetectBest([]byte(value))
                if err == nil {
                    if result.Charset == "ISO-8859-1" || result.Charset == "ISO-8859-9" {
                        //Меняем кодировку
                        r := transform.NewReader(strings.NewReader(value), charmap.Windows1251.NewEncoder())
                        buf, err := ioutil.ReadAll(r)
                        if err == nil {
                            tbl[row_idx][col_idx] = string(buf)
                        }
                    } else {
                        tbl[row_idx][col_idx] = value
                    }
                }
            }
        }
    }
    
    for row_idx, row := range tbl {
        for col_idx, cell := range row {
            beego.Info(row_idx, col_idx, cell)
        }
    }
    this.ServeJSON()
}