3

我正在尝试使用 python 和 pywin32 编写和创建 excel 文件的应用程序,并且我想使用用户使用的任何版本的 excel 的默认格式和扩展名保存文件。根据他们使用的 excel 版本,默认格式可能是使用“.xlsx”扩展名的“Open XML Workbook”。其他时候,它可能是基本的 excel 格式和“.xls”扩展名。另外,用户可以配置 excel 以使用其他一些默认格式。

我知道如何找到默认格式 (Application.DefaultSaveFormat) - 但我不知道如何确定该格式的默认扩展名。部分问题是我的文件名甚至在扩展名之前往往包含句点:
基本文件名是“filename.BOM”,所以实际文件名应该是“filename.BOM.xls”或“filename.BOM.xlsx”取决于默认格式。

如果我在文件名中没有双句点,一切都会好起来的。因此,如果默认格式为“Open XML Workbook”,Workbook.SaveAs(“filename”) 将创建一个名为“filename.xlsx”的文件。但是 Workbook.SaveAs("filename.BOM") 会创建一个名为“filename.BOM”的文件。当 Excel 在文件名中看到句点时,它不会添加默认扩展名。

我唯一能想到的是保存一个临时文件,从中获取扩展名,然后删除临时文件 - 但这似乎真的很笨拙。有人有更好的解决方案吗?

from tempfile import mktemp
from os import path
from os import remove as delfile
class excel:
    def __init__( self):
        self.app = DispatchEx( "Excel.Application" )
    def saveas_default_ext_format( self, workbook, filename):
        # filename - file name with path but without extension

        tmpname = mktemp()

        alerts = self.app.DisplayAlerts
        self.app.DisplayAlerts = False
        workbook.SaveAs( tmpname)
        self.app.DisplayAlerts = alerts

        tmpname = self.app.ActiveWorkbook.FullName
        x, ext = path.splitext( tmpname)
        fullname = filename + ext
        workbook.SaveAs( fullname)

        delfile( tmpname)

        return fullname
4

2 回答 2

4

由于很难在一个地方找到包含枚举、值和扩展的列表,所以我就是这样做的。棘手的部分是让枚举工作(参见代码)

import win32com
from os.path import splitext

XlFileFormats = [ 
    'xlAddIn'                      , # Microsoft Excel 97-2003 Add-In
    'xlAddIn8'                     , # Microsoft Excel 97-2003 Add-In
    'xlCSV'                        , # CSV
    'xlCSVMac'                     , # Macintosh CSV
    'xlCSVMSDOS'                   , # MSDOS CSV
    'xlCSVWindows'                 , # Windows CSV
    'xlCurrentPlatformText'        , # Current Platform Text
    'xlDBF2'                       , # DBF2
    'xlDBF3'                       , # DBF3
    'xlDBF4'                       , # DBF4
    'xlDIF'                        , # DIF
    'xlExcel12'                    , # Excel12
    'xlExcel2'                     , # Excel2
    'xlExcel2FarEast'              , # Excel2 FarEast
    'xlExcel3'                     , # Excel3
    'xlExcel4'                     , # Excel4
    'xlExcel4Workbook'             , # Excel4 Workbook
    'xlExcel5'                     , # Excel5
    'xlExcel7'                     , # Excel7
    'xlExcel8'                     , # Excel8
    'xlExcel9795'                  , # Excel9795
    'xlHtml'                       , # HTML format
    'xlIntlAddIn'                  , # International Add-In
    'xlIntlMacro'                  , # International Macro
    'xlOpenDocumentSpreadsheet'    , # OpenDocument Spreadsheet
    'xlOpenXMLAddIn'               , # Open XML Add-In
    'xlOpenXMLTemplate'            , # Open XML Template
    'xlOpenXMLTemplateMacroEnabled', # Open XML Template Macro Enabled
    'xlOpenXMLWorkbook'            , # Open XML Workbook
    'xlOpenXMLWorkbookMacroEnabled', # Open XML Workbook Macro Enabled
    'xlSYLK'                       , # SYLK
    'xlTemplate'                   , # Template
    'xlTemplate8'                  , # Template 8
    'xlTextMac'                    , # Macintosh Text
    'xlTextMSDOS'                  , # MSDOS Text
    'xlTextPrinter'                , # Printer Text
    'xlTextWindows'                , # Windows Text
    'xlUnicodeText'                , # Unicode Text
    'xlWebArchive'                 , # Web Archive
    'xlWJ2WD1'                     , # WJ2WD1
    'xlWJ3'                        , # WJ3
    'xlWJ3FJ3'                     , # WJ3FJ3
    'xlWK1'                        , # WK1
    'xlWK1ALL'                     , # WK1ALL
    'xlWK1FMT'                     , # WK1FMT
    'xlWK3'                        , # WK3
    'xlWK3FM3'                     , # WK3FM3
    'xlWK4'                        , # WK4
    'xlWKS'                        , # Worksheet
    'xlWorkbookDefault'            , # Workbook default
    'xlWorkbookNormal'             , # Workbook normal
    'xlWorks2FarEast'              , # Works2 FarEast
    'xlWQ1'                        , # WQ1
    'xlXMLSpreadsheet'             , # XML Spreadsheet
    ]

xl = win32com.client.gencache.EnsureDispatch( "Excel.Application")
'''if you use Dispatch( 'Excel.Application') without having run makepy first,
    the constants from XlFileFormats will not be available.
    See
    http://docs.activestate.com/activepython/2.4/pywin32/html/com/win32com/HTML/GeneratedSupport.html
    http://docs.activestate.com/activepython/2.4/pywin32/html/com/win32com/HTML/QuickStartClientCom.html
    '''
app = xl.Application
app.Visible = 1
book = app.Workbooks.Add(); book.Activate()
print 'DefaultSaveFormat:', app.DefaultSaveFormat

# you cannot access the constants until AFTER you have dispatched excel
constants = win32com.client.constants

print
app.DisplayAlerts = False
for formatName in XlFileFormats:
    formatNum = getattr( constants, formatName)
    print '%-35s: %5d,' % ( formatName, formatNum),
    try: book.SaveAs( r'C:\excel_file_formats\xlbook', formatNum)
    except Exception: print 'could not save this format'
    else:
        wbname, wbext = splitext( book.Name)
        print '"%s"' % ( wbext)
        del wbname, wbext
    #~ raw_input( '    paused')

app.Quit()

这是输出:

DefaultSaveFormat: 51

xlAddIn                            :    18, ".xls"
xlAddIn8                           :    18, ".xls"
xlCSV                              :     6, ".csv"
xlCSVMac                           :    22, ".csv"
xlCSVMSDOS                         :    24, ".csv"
xlCSVWindows                       :    23, ".csv"
xlCurrentPlatformText              : -4158, ".txt"
xlDBF2                             :     7, could not save this format
xlDBF3                             :     8, could not save this format
xlDBF4                             :    11, could not save this format
xlDIF                              :     9, ".dif"
xlExcel12                          :    50, ".xlsb"
xlExcel2                           :    16, could not save this format
xlExcel2FarEast                    :    27, could not save this format
xlExcel3                           :    29, could not save this format
xlExcel4                           :    33, could not save this format
xlExcel4Workbook                   :    35, could not save this format
xlExcel5                           :    39, ".xls"
xlExcel7                           :    39, ".xls"
xlExcel8                           :    56, ".xls"
xlExcel9795                        :    43, could not save this format
xlHtml                             :    44, ".htm"
xlIntlAddIn                        :    26, could not save this format
xlIntlMacro                        :    25, could not save this format
xlOpenDocumentSpreadsheet          :    60, ".ods"
xlOpenXMLAddIn                     :    55, ".ods" !!! this one is not right !!!
xlOpenXMLTemplate                  :    54, ".xltx"
xlOpenXMLTemplateMacroEnabled      :    53, ".xltm"
xlOpenXMLWorkbook                  :    51, ".xlsx"
xlOpenXMLWorkbookMacroEnabled      :    52, ".xlsm"
xlSYLK                             :     2, ".slk"
xlTemplate                         :    17, ".xlt"
xlTemplate8                        :    17, ".xlt"
xlTextMac                          :    19, ".txt"
xlTextMSDOS                        :    21, ".txt"
xlTextPrinter                      :    36, ".prn"
xlTextWindows                      :    20, ".txt"
xlUnicodeText                      :    42, ""
xlWebArchive                       :    45, ".mht"
xlWJ2WD1                           :    14, could not save this format
xlWJ3                              :    40, could not save this format
xlWJ3FJ3                           :    41, could not save this format
xlWK1                              :     5, could not save this format
xlWK1ALL                           :    31, could not save this format
xlWK1FMT                           :    30, could not save this format
xlWK3                              :    15, could not save this format
xlWK3FM3                           :    32, could not save this format
xlWK4                              :    38, could not save this format
xlWKS                              :     4, could not save this format
xlWorkbookDefault                  :    51, ".xlsx"
xlWorkbookNormal                   : -4143, ".xls"
xlWorks2FarEast                    :    28, could not save this format
xlWQ1                              :    34, could not save this format
xlXMLSpreadsheet                   :    46, ".xml"

我不知道为什么它无法保存某些格式;但它们似乎不是非常常见或有用的。

此外,xlOpenXMLAddIn 格式也很奇怪。它报告和扩展“.ods”——但这并不是它实际保存的内容。如果您删除已创建的任何文件,则将代码更改为使用 xlOpenXMLAddIn 格式仅运行一次

import win32com
from os.path import splitext
from time import sleep

xl = win32com.client.gencache.EnsureDispatch( "Excel.Application")
app = xl.Application
app.Visible = 1
book = app.Workbooks.Add(); book.Activate()
constants = win32com.client.constants

formatName = 'xlOpenXMLAddIn'
formatNum = getattr( constants, formatName)
print 'test_file_format: %s > %s' % ( formatName, formatNum)

app.DisplayAlerts = False
try: book.SaveAs( r'C:\excel_file_formats\xlbook', formatNum)
except Exception: print 'could not save this format'
else:
    wbname, wbext = splitext( book.Name)
    print '"%s" > "%s"' % ( wbname, wbext)

你得到这个:

test_file_format: xlOpenXMLAddIn > 55
"Book1" > ""

它创建的文件将命名为“xlbook.xlam”;但 excel 的标题栏显示“Book1 - Microsoft Excel”。所以我不确定这是怎么回事。无论如何,这似乎不是一种非常有用的格式。

于 2012-11-16T21:20:56.117 回答
0

为什么不制作 xlfileformats:extensions 的字典并使用它进行查找:

from tempfile import mktemp
from os import path
from os import remove as delfile
class excel:
    def __init__( self):
        self.app = DispatchEx( "Excel.Application" )
        self.dct =     {51:'xlsx',
                        52:'xlsm',
                        50:'xlsb',
                        56:'xls'
                        }

    def saveas_default_ext_format( self, workbook, filename):
        # filename - file name with path but without extension


        fullname = '.'.join((filename, self.dct[self.app.DefaultSaveFormat]))
        workbook.SaveAs( fullname)

        return fullname

我只在示例字典中包含了最常见的格式,但您可以从网络上的许多资源中充实它,例如这里。我没有放入 KeyError 异常处理程序,但您可能需要一个。

祝你好运,迈克

于 2012-11-15T23:50:12.577 回答