pyUno - как установить кодировку при открытии

Автор stlex, 24 августа 2016, 17:32

0 Пользователи и 1 гость просматривают эту тему.

stlex

Здравствуйте! использую pyUno, пытаюсь выставить кодировку при открытии текстового файла, безуспешно.

def _toProperties(self, dict):
        props = []
        for key in dict:
            prop = PropertyValue()
            prop.Name = key
            prop.Value = dict[key]
            props.append(prop)
        return tuple(props)
....
        loadProperties = { Hidden": False, "CharacterSet": "Windows-1251" }
        document = self.desktop.loadComponentFromURL(inputUrl, "_blank", 0, self._toProperties(loadProperties))

А где вообще можно найти правильные значения опции "CharacterSet"?
Всем Спасибо!

economist

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

rami

Цитата: stlex от 24 августа 2016, 15:32пытаюсь выставить кодировку при открытии текстового файла, безуспешно.
Насколько я знаю, у фильтров импорта текстовых файлов нет параметров. Интересно посмотреть на файл.

stlex

Файл, и результат его импорта в pdf, ромбы вместо русских букв. Если убрать "Hidden": True, при импорте скриптом он на секунду показывается в окне, и видно, что кодировка не распознана. Если через интерфейс OO, то кодировка определяется. А на питоне со всеми файлами так

economist

Странно, cod.txt 100% в кодировке "Windows-1251".

А что значит "результат его импорта в pdf" - это в коде где?
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

economist

Попробуйте считать TXT файл построчно и ЯВНО декодируйте строку:

cod=open('C:/cod.txt', 'r')
for line in cod:
    linenew=line.decode('cp1251') # Декодировали (это TXT от WIN/1С/MSO итп) в utf-8
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

rami

Цитата: stlex от 25 августа 2016, 06:19Если через интерфейс OO, то кодировка определяется
Это как определяется?

Можно прочитать содержимое текстового файла (.txt) в нужной кодировке и "перелить" его содержимое в новый документ (.odt) и уже новый документ сохранить как .pdf. Так подойдёт?

stlex

Цитата: economist от 25 августа 2016, 10:07А что значит "результат его импорта в pdf" - это в коде где?
вот весь скрипт

#!/usr/bin/python
#
# PyODConverter (Python OpenDocument Converter) v1.2 - 2012-03-10
#
# This script converts a document from one office format to another by
# connecting to an OpenOffice.org instance via Python-UNO bridge.
#
# Copyright (C) 2008-2012 Mirko Nasato
# Licensed under the GNU LGPL v2.1 - http://www.gnu.org/licenses/lgpl-2.1.html
# - or any later version.
#
DEFAULT_OPENOFFICE_PORT = 2002

import uno
import os
from os.path import abspath, isfile, splitext
from com.sun.star.beans import PropertyValue
from com.sun.star.task import ErrorCodeIOException
from com.sun.star.connection import NoConnectException

FAMILY_TEXT = "Text"
FAMILY_WEB = "Web"
FAMILY_SPREADSHEET = "Spreadsheet"
FAMILY_PRESENTATION = "Presentation"
FAMILY_DRAWING = "Drawing"

#---------------------#
# Configuration Start #
#---------------------#

# see http://wiki.services.openoffice.org/wiki/Framework/Article/Filter

# most formats are auto-detected; only those requiring options are defined here
IMPORT_FILTER_MAP = {
    "txt": {
        "FilterName": "Text (encoded)",
        "FilterOptions": "utf8"
    },
    "csv": {
        "FilterName": "Text - txt - csv (StarCalc)",
        "FilterOptions": "44,34,0"
    }
}

EXPORT_FILTER_MAP = {
    "pdf": {
        FAMILY_TEXT: { "FilterName": "writer_pdf_Export" },
        FAMILY_WEB: { "FilterName": "writer_web_pdf_Export" },
        FAMILY_SPREADSHEET: { "FilterName": "calc_pdf_Export" },
        FAMILY_PRESENTATION: { "FilterName": "impress_pdf_Export" },
        FAMILY_DRAWING: { "FilterName": "draw_pdf_Export" }
    },
    "html": {
        FAMILY_TEXT: { "FilterName": "HTML (StarWriter)" },
        FAMILY_SPREADSHEET: { "FilterName": "HTML (StarCalc)" },
        FAMILY_PRESENTATION: { "FilterName": "impress_html_Export" }
    },
    "odt": {
        FAMILY_TEXT: { "FilterName": "writer8" },
        FAMILY_WEB: { "FilterName": "writerweb8_writer" }
    },
    "doc": {
        FAMILY_TEXT: { "FilterName": "MS Word 97" }
    },
    "rtf": {
        FAMILY_TEXT: { "FilterName": "Rich Text Format" }
    },
    "txt": {
        FAMILY_TEXT: {
            "FilterName": "Text"
            #"FilterOptions": "Windows-1251"
        }
    },
    "ods": {
        FAMILY_SPREADSHEET: { "FilterName": "calc8" }
    },
    "xls": {
        FAMILY_SPREADSHEET: { "FilterName": "MS Excel 97" }
    },
    "csv": {
        FAMILY_SPREADSHEET: {
            "FilterName": "Text - txt - csv (StarCalc)",
            "FilterOptions": "44,34,0"
        }
    },
    "odp": {
        FAMILY_PRESENTATION: { "FilterName": "impress8" }
    },
    "ppt": {
        FAMILY_PRESENTATION: { "FilterName": "MS PowerPoint 97" }
    },
    "swf": {
        FAMILY_DRAWING: { "FilterName": "draw_flash_Export" },
        FAMILY_PRESENTATION: { "FilterName": "impress_flash_Export" }
    }
}

PAGE_STYLE_OVERRIDE_PROPERTIES = {
    FAMILY_SPREADSHEET: {
        #--- Scale options: uncomment 1 of the 3 ---
        # a) 'Reduce / enlarge printout': 'Scaling factor'
        "PageScale": 100,
        # b) 'Fit print range(s) to width / height': 'Width in pages' and 'Height in pages'
        #"ScaleToPagesX": 1, "ScaleToPagesY": 1000,
        # c) 'Fit print range(s) on number of pages': 'Fit print range(s) on number of pages'
        #"ScaleToPages": 1,
        "PrintGrid": False
    }
}

#-------------------#
# Configuration End #
#-------------------#

class DocumentConversionException(Exception):

    def __init__(self, message):
        self.message = message

    def __str__(self):
        return self.message


class DocumentConverter:
   
    def __init__(self, port=DEFAULT_OPENOFFICE_PORT):
        localContext = uno.getComponentContext()
        resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext)
        try:
            context = resolver.resolve("uno:socket,host=localhost,port=%s;urp;StarOffice.ComponentContext" % port)
        except NoConnectException:
            raise DocumentConversionException, "failed to connect to OpenOffice.org on port %s" % port
        self.desktop = context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context)

    def convert(self, inputFile, outputFile):

        inputUrl = self._toFileUrl(inputFile)
        outputUrl = self._toFileUrl(outputFile)

        loadProperties = { "Hidden": True }
        inputExt = self._getFileExt(inputFile)
        if IMPORT_FILTER_MAP.has_key(inputExt):
            loadProperties.update(IMPORT_FILTER_MAP[inputExt])
       
        document = self.desktop.loadComponentFromURL(inputUrl, "_blank", 0, self._toProperties(loadProperties))
        try:
            document.refresh()
        except AttributeError:
            pass

        family = self._detectFamily(document)
        #self._overridePageStyleProperties(document, family)
       
        outputExt = self._getFileExt(outputFile)
        storeProperties = self._getStoreProperties(document, outputExt)

        try:
            document.storeToURL(outputUrl, self._toProperties(storeProperties))
        finally:
            document.close(True)

    def _overridePageStyleProperties(self, document, family):
        if PAGE_STYLE_OVERRIDE_PROPERTIES.has_key(family):
            properties = PAGE_STYLE_OVERRIDE_PROPERTIES[family]
            pageStyles = document.getStyleFamilies().getByName('PageStyles')
            for styleName in pageStyles.getElementNames():
                pageStyle = pageStyles.getByName(styleName)
                for name, value in properties.items():
                    pageStyle.setPropertyValue(name, value)

    def _getStoreProperties(self, document, outputExt):
        family = self._detectFamily(document)
        try:
            propertiesByFamily = EXPORT_FILTER_MAP[outputExt]
        except KeyError:
            raise DocumentConversionException, "unknown output format: '%s'" % outputExt
        try:
            return propertiesByFamily[family]
        except KeyError:
            raise DocumentConversionException, "unsupported conversion: from '%s' to '%s'" % (family, outputExt)
   
    def _detectFamily(self, document):
        if document.supportsService("com.sun.star.text.WebDocument"):
            return FAMILY_WEB
        if document.supportsService("com.sun.star.text.GenericTextDocument"):
            # must be TextDocument or GlobalDocument
            return FAMILY_TEXT
        if document.supportsService("com.sun.star.sheet.SpreadsheetDocument"):
            return FAMILY_SPREADSHEET
        if document.supportsService("com.sun.star.presentation.PresentationDocument"):
            return FAMILY_PRESENTATION
        if document.supportsService("com.sun.star.drawing.DrawingDocument"):
            return FAMILY_DRAWING
        raise DocumentConversionException, "unknown document family: %s" % document

    def _getFileExt(self, path):
        ext = splitext(path)[1]
        if ext is not None:
            return ext[1:].lower()

    def _toFileUrl(self, path):
        return uno.systemPathToFileUrl(abspath(path))

    def _toProperties(self, dict):
        props = []
        for key in dict:
            prop = PropertyValue()
            prop.Name = key
            prop.Value = dict[key]
            props.append(prop)
        return tuple(props)


if __name__ == "__main__":
    from sys import argv, exit
   
    if len(argv) < 3:
        print "USAGE: python %s <input-file> <output-file>" % argv[0]
        exit(255)
    if not isfile(argv[1]):
        print "no such input file: %s" % argv[1]
        exit(1)

    try:
    print os.environ
        converter = DocumentConverter()   
        converter.convert(argv[1], argv[2])
    except DocumentConversionException, exception:
        print "ERROR! " + str(exception)
        exit(1)
    except ErrorCodeIOException, exception:
        print "ERROR! ErrorCodeIOException %d" % exception.ErrCode
        exit(1)


stlex

Цитата: rami от 25 августа 2016, 10:24Можно прочитать содержимое текстового файла (.txt) в нужной кодировке и "перелить" его содержимое в новый документ (.odt) и уже новый документ сохранить как .pdf. Так подойдёт?
Да, если предварительно перекодировать в utf8, все нормально.
Спасибо!

economist

Кому приходится перекодировать многомегабайтные TXT из WIN в UTF-8?  :)
Вот самый быстрый способ (скрипт VBS под Windows). Быстрее Питона в 2-3 раза.
Примерно скорость на уровне написанных на С утилит.


Set stream = CreateObject("ADODB.Stream")
stream.Type = 2
stream.Charset = "windows-1251"
stream.Open()
stream.LoadFromFile("M:\win-1251 text.txt")
Text = stream.ReadText()
stream.Close()
stream.Charset = "UTF-8"
stream.Open()
stream.WriteText(Text)
stream.SaveToFile "M:\utf-8 text.txt", 2
stream.Close()
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

kompilainenn

Цитата: economist от 25 августа 2016, 14:32Кому приходится перекодировать многомегабайтные TXT из WIN в UTF-8? 
Вот самый быстрый способ (скрипт VBS под Windows). Быстрее Питона в 2-3 раза.
Примерно скорость на уровне написанных на С утилит.
для тупых и далеких от программирования и администрирования пользователей поясните: что с этим текстом дальше делать? его нужно оформить в файл? какое расширение у файла? как потом его запускать? и так далее. Спасибо
Поддержать разработчиков LibreOffice можно тут, а наш форум вот тут

economist

kompilainenn - Да, код из сообщения 111 нужно сохранить в виде файла с расширением VBS (Visual Basic Script).
Далее, щелкнув по этому файлу ПКМ (он откроется в блокноте, или просто открыть его в блокноте ч/з Файл - Открыть - Все файлы...) - нужно в скрипте вместо "M:\win-1251 text.txt" написать полный путь к Вашему файлу, который нужно перекодировать. После чего закрыть, сохранить и можно запускать VBS-файл двойным щелчком ЛКМ из любого места, даже ярлыком с Рабочего стола. Визуально при этом ничего происходить не будет, поэтому желательно в код вставить такую строчку (внизу), выводящее сообщение что все ОК.


ans = MsgBox("Перекодировка файла из WIN-1251 в UTF-8 успешно завершена!"), vbInformation


Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

economist

stlex - выбрав PyUno, вы пошли самым трудным, но почетным путём. Если задача в том чтобы сделать из TXT сразу PDF - есть консольные утилиты. Если нужно что-то в TXT пересчитать - заверните логику в VBS/BAT/BASH-скрипт. Чтобы сделать его форматированным - да, тут нужен OpenOffice или LibreOffice. Проще всего решить эту проблему на StarBasic или VBA в режиме Option VBASupport 1, Option Compatible. То есть вы читаете текстовый файл построчно и записываете его во Writer/Calc, откуда он экспортируется в PDF. Преимущества BASIC - пошаговая отладка, простота, скорость разработки.

PyUno, на мой взгляд, нужен для тех систем, где Питон является основным языком. Например, в свободной системе уровня ERP - ODOO (потеснившей SAP аж на 2-3 млрд. долларов), написанной на Питоне - пиуно используется для формирования и изменения уже существующих документов/отчетов итп.

Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...