【问题标题】:Print Excel files with Microsoft.Office.Interop.Excel and CLR in Python?在 Python 中使用 Microsoft.Office.Interop.Excel 和 CLR 打印 Excel 文件?
【发布时间】:2015-03-19 00:13:28
【问题描述】:

我一直在寻找许多方法来在不打开 Excel 应用程序的情况下打印 excel 文件,我在 C# 中使用了 Microsoft.Office.Interop.Excel,它运行良好,所以我决定寻找一种方法为了让它也能在 python 中运行,我找到了 IronPython,但我只需要 python,然后我发现 pythonnet 可以让 .NET 程序集在 python 中运行。

问题是从源 https://github.com/pythonnet/pythonnet 安装它(或试图) 它给了我一个关于找不到 Windows SDK 或其他东西的错误。

然后我通过pip安装了它,安装成功,但是当我尝试导入或添加引用时显示另一个错误:

 Unable to find assembly 'Microsoft.Office.Interop.Excel'.
   at Python.Runtime.CLRModule.AddReference(String name)

我已经从here 下载并安装了互操作程序集,因此应该安装它们。

我找到了一种使用 IronPython 和 Interop dll 在here 中打印 excel 文件的方法。

我的主要问题是我需要在不打开 Excel 应用程序的情况下打印一些 excel 文件,如果您有其他选择,欢迎您

如果没有其他选择,我应该怎么做才能让它找到程序集?


附加信息:为了在 C# 中打印,我使用了这个:

Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
String CompletePath = path;
Microsoft.Office.Interop.Excel.Workbook wb = excelApp.Workbooks.Open(CompletePath,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Type.Missing, Type.Missing, Type.Missing, Type.Missing);
Microsoft.Office.Interop.Excel.Worksheet ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets[1];
try
{

    // Open the Workbook:

    // Get the first worksheet.
    // (Excel uses base 1 indexing, not base 0.)
    ws.PageSetup.Orientation = Microsoft.Office.Interop.Excel.XlPageOrientation.xlLandscape;
    ws.PageSetup.FitToPagesTall = 1;
    ws.PageSetup.FitToPagesWide = 1;

    ws.PageSetup.TopMargin = 0;
    ws.PageSetup.HeaderMargin = 0;
    ws.PageSetup.RightMargin = 0;
    ws.PageSetup.LeftMargin = 0;
    ws.PageSetup.BottomMargin = 0;
    ws.PageSetup.FooterMargin = 0;
    ws.PageSetup.CenterVertically = true;
    ws.PageSetup.CenterHorizontally = true;

    //ws.PageSetup.Zoom = false;
    ws.PrintOut(Type.Missing, Type.Missing, Type.Missing, Type.Missing, PrinterName, Type.Missing, Type.Missing, Type.Missing);
    return true;
}
catch (Exception ex)
{
    LogSystem.TextLog.create();
    LogSystem.TextLog.Write("ERROR ", LogSystem.ErrorType.Error, DateTime.Now, ex.Message);
    return false;
}

finally 
{
    // Cleanup:
    GC.Collect();
    GC.WaitForPendingFinalizers();
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ws);
    wb.Close(false, Type.Missing, Type.Missing);
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(wb);
    excelApp.Quit();
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excelApp);
}

【问题讨论】:

标签: python .net excel printing python.net


【解决方案1】:

虽然我相信有一种方法可以使用 win32com.client (there is a good example) 自动化 Excel,但使用 .net 包装 com 互操作代码并使用 Python.Net 公开它可能会很有用。考虑因素可能是 .Net 对 com 互操作的更好支持和简单性,但您应该考虑到 Python.Net 本身并不完美,并且多年来没有积极开发。

接下来是方法:

  1. 使用 .net 编写代码并使用尽可能简单的界面公开此代码
    避免暴露 COM 类型!
    避免管理状态!
  2. 使用 python 中的库。

第一步

  • 创建名为 ExcelToolsLibrary 的新 .Net ClassLibrary 项目
  • 添加对 Microsoft.Office.Interop.Excel 的引用
  • 在此处放置下一个代码:

    namespace ExcelTools
    {
    using System;
    using Microsoft.Office.Interop.Excel;
    public class ExcelPrinter
    {
        public bool PrintFile(string fileName, string printerName) 
        {
            var excel = new Application();
            var workbook = excel.Workbooks.Open(fileName);
            var worksheet = (Worksheet)workbook.Worksheets[1];
            try
            {
                SetupPage(worksheet);
                worksheet.PrintOut(ActivePrinter: printerName ?? Type.Missing);
                workbook.Close(false);
                return true;
            }
            catch (Exception ex)
            {
                LogError(ex);
                return false;
            }
            finally
            {
                DisposeExcelObjects(excel,worksheet,workbook);
            }
        }
        private void SetupPage(Worksheet worksheet)
        {
            worksheet.PageSetup.Orientation = XlPageOrientation.xlLandscape;
            //put additional page setup here
        }
    
        private void LogError(Exception e)
        {
            //add your logging
        }
    
        private void DisposeExcelObjects(Application excelApp,params object[] comObjects)
        {
            try
            {
                foreach (var obj in comObjects)
                    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj);    
                excelApp.Quit();
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(excelApp);    
            }
            catch (Exception e)
            {
                LogError(e);
            }
        }
    
    }
    }
    

第 2 步

在python中使用这个库:

  • 构建项目并将 ExcelToolsLibrary.dll 从输出放置到 可从路径获得的任何位置(您可以为此使用.pth file)。
  • 导入库并像这样使用它:

    import clr
    clr.AddReference("ExcelToolsLibrary") # 'ExcelToolsLibrary' is a dll name without the path
    import ExcelTools # 'ExcelTools' is a .Net namespace
    printer = ExcelTools.ExcelPrinter()
    printer.PrintFile(fileName,None) # None means that will be printed on default printer
    

【讨论】:

猜你喜欢
  • 2016-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多