Python - 从创建的 Excel 工作簿生成 PDF - 无法保存 pdf 文档

问题描述 投票:0回答:2

我正在尝试从 .xlsx worbook 生成 PDF 文件。 首先,我使用另一个工作簿的数据创建了一个新工作簿(进行了一些额外的数据转换)。 然后,我将新工作簿保存到临时路径中。 然后,我想打开创建的 .xlsx 并将其保存为 PDF 文件。

但是当我试图保存它时,我收到了这条消息:

Błąd: (-2147352567, 'Wystąpił wyjątek.', (0, 'Microsoft Excel', 'Nie zapisano dokumentu. Być może jest on otwarty lub przy zapisywaniu napotkano błąd.', 'xlmain11.chm', 0, -2146827284), None)

(它是波兰语)

The document was not saved. Perhaps it is open or an error was encountered when saving it

没有代码,应该保存 .pdf 文件,.xlsx 文件正在正确创建。

我的程序代码:

import sys
import openpyxl
from openpyxl import Workbook
from openpyxl.drawing.image import Image
from openpyxl.utils import get_column_letter
from tkinter.filedialog import asksaveasfile
import os
from win32com import client

initialFile = sys.argv[1]
initialCatalog = sys.argv[2]
assetsCatalog = f"{initialCatalog}\\api\\assets"

def codeToPictogram(code):
  for files in os.walk(assetsCatalog):
      if f'{code}.png' in files[2]:
          return 1
      else:
          return 0

try:
    wb = openpyxl.load_workbook(initialFile)
    ws = wb.active
    ws.title = "Stan techniczny nawierzchni"

    for row in ws.iter_cols(min_row=2, min_col=2, max_row=ws.max_row, max_col=ws.max_column):  
        for cell in row:  
            if(cell.value is None):
                continue
            if (codeToPictogram(cell.value) == 1):
                img = Image(f"{assetsCatalog}\\{cell.value}.png")
                img.height = 100
                img.width = 100
                ws.add_image(img, f"{get_column_letter(cell.column)}{cell.row}")
    file = asksaveasfile(defaultextension='.pdf',title = 'Zapisz stan techniczny', filetypes=[("Plik PDF", "*.pdf")])
    if file is not None:
        wb.save(f'{initialCatalog}\\api\\temp\\temp.xlsx')
        # wb.close()
        
        excel = client.Dispatch("Excel.Application")
        sheets = excel.Workbooks.Open(f'{initialCatalog}\\api\\temp\\temp.xlsx')
        work_sheets = sheets.Worksheets[0]
        work_sheets.ExportAsFixedFormat(0, file.name)
        
        print("Gotowe!")
        input("Wciśnij Enter, aby zamknąć...")
except Exception as e:
    print(f"Błąd: {e}")
    input("Wciśnij Enter, aby zamknąć...")

我尝试使用

wb.close()
,但没有成功。 我正在查看 openpyxl 文档,但我没有找到任何方法将新工作簿另存为 .pdf 而不是先将其另存为 .xlsx。

这是我第一次尝试做一个 Python 应用程序,所以也许有一些我不知道的简单到愚蠢的事情。 我正在尝试从 C# 改编 :)

我会很感激任何帮助

python excel pdf openpyxl
2个回答
0
投票

我认为你有两个主要问题

  1. asksaveasfile
    创建一个 textIowrapper。在那个点创建一个不能被覆盖的文件
  2. 您可能没有阅读正确的表格以转换为 pdf

无论哪种方式,我相信您的代码在尝试编写 pdf 时会爆炸,因为当时命名的 pdf 是一个 open 文件.
您需要一个字符串作为文件名,因此请尝试将

asksaveasfile
更改为
asksaveasfilename
,这不会创建文件并返回一个字符串。或者因为您无论如何都在使用 win32com,请使用
GetSaveAsFilename


以下代码示例修改您的代码;

  1. 更改文件名请求以使用 win32com
  2. work_sheets
    设置为命名表
    "Stan techniczny nawierzchni"
  3. 关闭win32客户端
    GetSaveAsFilename
  4. 删除临时 xlsx 文件(可选)

此代码示例成功创建了 pdf 并删除了临时 xlsx 文件,没有留下僵尸 Excel 进程。

...
    # file = asksaveasfile(defaultextension='.pdf', title='Zapisz stan techniczny', filetypes=[("Plik PDF", "*.pdf")])
    ### Change file name input
    samplefilename = 'PDF_Filename.pdf'
    excel = client.Dispatch("Excel.Application")
    file = excel.GetSaveAsFilename(samplefilename,
                                   FileFilter="PDF Files (*.pdf), *.pdf",
                                   Title='Zapisz stan techniczny')

    if file is not None:
        wb.save(f'{initialCatalog}\\api\\temp\\temp.xlsx')

        sheets = excel.Workbooks.Open(f'{initialCatalog}\\api\\temp\\temp.xlsx')
        ### Be sure the sheet you are saving is the right one
        work_sheets = sheets.Worksheets["Stan techniczny nawierzchni"]
        work_sheets.ExportAsFixedFormat(0, file)
        ### Close the win32 instance
        sheets.Close(True)

        ### Now you can remove the xlsx file
        os.remove(f'{initialCatalog}\\api\\temp\\temp.xlsx')

        print("Gotowe!")
        input("Wciśnij Enter, aby zamknąć...")
except Exception as e:
    print(f"Błąd: {e}")
    input("Wciśnij Enter, aby zamknąć...")

-1
投票

问题是 temp.xlsx 没有关闭 Excel。 Excel 仍处于活动状态并且有文件锁定。所以当你试图写入它时,文件被锁定了。

我不确定对此的解决方案,但您可以针对此用例试用 pandas,而不是保存到临时文件。

© www.soinside.com 2019 - 2024. All rights reserved.