1

我一直在寻找多种方法来打印 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)

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

我在这里找到了一种使用 IronPython 和 Interop dll打印 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);
}
4

1 回答 1

1

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

接下来的方法是:

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

步骤1

  • 创建名为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 文件)。
  • 导入库并像这样使用它:

    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
    
于 2015-02-15T10:06:41.127 回答