web-dev-qa-db-ja.com

.doc to pdf to python

私は大量の.docファイルを.pdfに変換する仕事をしています。そして、スーパーバイザーが私にこれをさせたい唯一の方法は、MSWord 2010を使用することです。python COMオートメーションを使用してこれを自動化できるはずです。いくつかのチュートリアルを検索しようとしましたが、何も見つかりませんでした(もしかすると私は持っているかもしれませんが、何を探しているのかわかりません)。

今、私は this を読んでいます。これがどれほど役立つかわからない。

33
nik

comtypes を使用した単純な例、単一ファイルの変換、コマンドライン引数として指定された入力および出力ファイル名:

import sys
import os
import comtypes.client

wdFormatPDF = 17

in_file = os.path.abspath(sys.argv[1])
out_file = os.path.abspath(sys.argv[2])

Word = comtypes.client.CreateObject('Word.Application')
doc = Word.Documents.Open(in_file)
doc.SaveAs(out_file, FileFormat=wdFormatPDF)
doc.Close()
Word.Quit()

pywin32 を使用することもできますが、これは以下を除いて同じです:

import win32com.client

その後:

Word = win32com.client.Dispatch('Word.Application')
56
Steven

私は半日この問題に取り組んできたので、この問題に関する私の経験の一部を共有すべきだと思います。スティーブンの答えは正しいですが、私のコンピューターでは失敗します。ここでそれを修正する2つのキーポイントがあります。

(1)。 「Word.Application」オブジェクトを初めて作成したときは、ドキュメントを開く前に(Wordアプリ)オブジェクトを表示する必要があります。 (実際、私でもこれが機能する理由を説明することはできません。コンピューターでこれを行わないと、不可視モデルで文書を開こうとするとプログラムがクラッシュし、「Word.Application」オブジェクトが削除されます。 OS。)

(2)。 (1)を実行すると、プログラムはときどき正常に動作しますが、頻繁に失敗する場合があります。クラッシュエラー"COMError: (-2147418111, 'Call was rejected by callee.', (None, None, None, 0, None))"は、COMサーバーがそれほど迅速に応答できない可能性があることを意味します。そのため、ドキュメントを開こうとする前に遅延を追加します。

これらの2つのステップを実行すると、プログラムはエラーなしで完全に動作します。デモコードは以下の通りです。同じ問題が発生した場合は、次の2つの手順を試してください。それが役に立てば幸い。

    import os
    import comtypes.client
    import time


    wdFormatPDF = 17


    # absolute path is needed
    # be careful about the slash '\', use '\\' or '/' or raw string r"..."
    in_file=r'absolute path of input docx file 1'
    out_file=r'absolute path of output pdf file 1'

    in_file2=r'absolute path of input docx file 2'
    out_file2=r'absolute path of outputpdf file 2'

    # print out filenames
    print in_file
    print out_file
    print in_file2
    print out_file2


    # create COM object
    Word = comtypes.client.CreateObject('Word.Application')
    # key point 1: make Word visible before open a new document
    Word.Visible = True
    # key point 2: wait for the COM Server to prepare well.
    time.sleep(3)

    # convert docx file 1 to pdf file 1
    doc=Word.Documents.Open(in_file) # open docx file 1
    doc.SaveAs(out_file, FileFormat=wdFormatPDF) # conversion
    doc.Close() # close docx file 1
    Word.Visible = False
    # convert docx file 2 to pdf file 2
    doc = Word.Documents.Open(in_file2) # open docx file 2
    doc.SaveAs(out_file2, FileFormat=wdFormatPDF) # conversion
    doc.Close() # close docx file 2   
    Word.Quit() # close Word Application 
7
Yang

unoconv(Pythonで記述)およびヘッドレスデーモンとして実行されているopenoffice。 http://dag.wiee.rs/home-made/unoconv/

doc、docx、ppt、pptx、xls、xlsxで非常にうまく機能します。ドキュメントを変換したり、サーバー上の特定の形式に保存/変換する必要がある場合に非常に便利です

4
lxx

PowerShell を使用してもかまわない場合は、これをご覧ください Hey、Scripting Guy!の記事 。提示されたコードは、wdFormatPDFWdSaveFormat列挙値を使用するために採用できます( here を参照)。 このブログ記事 は同じアイデアの異なる実装を示しています。

2
Bas Bossink

スティーブンスの答えが機能することは注目に値しますが、forループを使用して複数のファイルをエクスポートし、ループの前にClientObjectまたはDispatchステートメントを配置する場合は必ず確認してください-一度だけ作成する必要があります-私の問題を参照してください: Python win32com.client.Dispatchは、Word文書をループしてPDFにエクスポートします。次のループが発生すると失敗します

2
James N

受け入れられた答えを試してみましたが、Wordが生成する肥大化したPDFには特に熱心ではありませんでした。仮想PDFプリンターを使用するときにダイアログを無効にする方法を探した後、Bullzip PDFプリンターに出会い、その機能にかなり感銘を受けました。以前に使用した他の仮想プリンタを置き換えました。ダウンロードページに「無料コミュニティエディション」があります。

COM APIは here にあり、使用可能な設定のリストは here にあります。設定は、1つの印刷ジョブにのみ使用される「runonce」ファイルに書き込まれ、自動的に削除されます。複数のPDFを印刷する場合、各ファイルで設定が正しく使用されるように、別の印刷ジョブを開始する前に1つの印刷ジョブが完了していることを確認する必要があります。

import os, re, time, datetime, win32com.client

def print_to_Bullzip(file):
    util = win32com.client.Dispatch("Bullzip.PDFUtil")
    settings = win32com.client.Dispatch("Bullzip.PDFSettings")
    settings.PrinterName = util.DefaultPrinterName      # make sure we're controlling the right PDF printer

    outputFile = re.sub("\.[^.]+$", ".pdf", file)
    statusFile = re.sub("\.[^.]+$", ".status", file)

    settings.SetValue("Output", outputFile)
    settings.SetValue("ConfirmOverwrite", "no")
    settings.SetValue("ShowSaveAS", "never")
    settings.SetValue("ShowSettings", "never")
    settings.SetValue("ShowPDF", "no")
    settings.SetValue("ShowProgress", "no")
    settings.SetValue("ShowProgressFinished", "no")     # disable balloon tip
    settings.SetValue("StatusFile", statusFile)         # created after print job
    settings.WriteSettings(True)                        # write settings to the runonce.ini
    util.PrintFile(file, util.DefaultPrinterName)       # send to Bullzip virtual printer

    # wait until print job completes before continuing
    # otherwise settings for the next job may not be used
    timestamp = datetime.datetime.now()
    while( (datetime.datetime.now() - timestamp).seconds < 10):
        if os.path.exists(statusFile) and os.path.isfile(statusFile):
            error = util.ReadIniString(statusFile, "Status", "Errors", '')
            if error != "0":
                raise IOError("PDF was created with errors")
            os.remove(statusFile)
            return
        time.sleep(0.1)
    raise IOError("PDF creation timed out")
1
user2921789

SaveAs関数の代替として、Wordで通常表示されるPDFオプションダイアログにアクセスできるExportAsFixedFormatを使用することもできます。これにより、ブックマークやその他のドキュメントプロパティを指定できます。

doc.ExportAsFixedFormat(OutputFileName=pdf_file,
    ExportFormat=17, #17 = PDF output, 18=XPS output
    OpenAfterExport=False,
    OptimizeFor=0,  #0=Print (higher res), 1=Screen (lower res)
    CreateBookmarks=1, #0=No bookmarks, 1=Heading bookmarks only, 2=bookmarks match Word bookmarks
    DocStructureTags=True
    );

関数の引数の完全なリストは、「OutputFileName」、「ExportFormat」、「OpenAfterExport」、「OptimizeFor」、「Range」、「From」、「To」、「Item」、「IncludeDocProps」、「KeepIRM」、「CreateBookmarks」です。 '、' DocStructureTags '、' BitmapMissingFonts '、' UseISO19005_1 '、' FixedFormatExtClassPtr '

0
patrick

いわゆる仮想PDFプリントドライバーの調査から始める必要があります。すぐに見つかると、DOCファイルをPDFファイルに印刷するバッチファイルを作成できるはずです。これはおそらくPythonでも実行できます(MSWordでプリンタードライバー出力を設定し、ドキュメント/印刷コマンドを発行します。後でコマンドラインAFAIRを使用して実行できます)。

0
c-smile