如何使用Windows 10自带的Microsoft Print To PDF打印机,在C#中编程实现无需提示文件名即可将内容打印到PDF文件中

66
Microsoft Windows 10带有一个可以将内容打印成PDF文件的Microsoft Print To PDF 打印机。它会提示输入下载文件名。
如何使用C#编程实现对其进行控制,避免提示PDF文件名,而是保存到我提供的某个文件夹中指定的文件名?
这是为了批量处理大量文档或其他类型的文件以进行程序化PDF打印。

我为你提供了一个可行的解决方案。请告诉我你的想法 :) - Kraang Prime
2
如果微软在他们的软件中自带此类选项(自动命名功能),那将会是多么简单且极大的帮助啊! - Avatar
请查看此答案:https://dev59.com/plMH5IYBdhLWcg3wvh6E#58566537 - Shahin Dohan
3个回答

59

使用纯代码的方式,在不提示文件名的情况下打印PrintDocument对象,使用Microsoft Print to PDF打印机,以下是实现方法:

// generate a file name as the current date/time in unix timestamp format
string file = (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds.ToString();

// the directory to store the output.
string directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

// initialize PrintDocument object
PrintDocument doc = new PrintDocument() {
    PrinterSettings = new PrinterSettings() {
        // set the printer to 'Microsoft Print to PDF'
        PrinterName = "Microsoft Print to PDF",

        // tell the object this document will print to file
        PrintToFile = true,

        // set the filename to whatever you like (full path)
        PrintFileName = Path.Combine(directory, file + ".pdf"),
    }
};

doc.Print();

您还可以使用此方法处理其他 另存为文件 类型的打印机,如 Microsoft XPS 打印机


8
我该怎么使用这个来使用Microsoft Print To PDF重新打印现有的PDF文件,例如将注释“嵌入”到PDF文件中? - clocktown
1
@KraangPrime,我使用了这种方法。它生成了一个文件,但是Adobe Reader无法打开该文件,显示文件已损坏。但是如果我不使用PrinterSettings,则会弹出浏览目标位置和文件名的窗口,然后我就可以访问该文件。我有什么遗漏吗..? - user3157132
7
这里输入的文件在哪里?除非我们订阅“PrintPage”事件并在那里进行图形操作,否则这不起作用,至少对我来说似乎非常复杂。也许我只是漏掉了什么? - Shahin Dohan
7
打印一个空文件?我看不到你往文件里添加任何内容。 - joym8
1
@KraangPrime,如果您有时间,能否回复用户@Shahin Dohan@joym8?我也有同样的问题。 - nam
显示剩余8条评论

0
我有同样的问题,所以我尝试了之前的解决方案,并遇到了评论中提到的同样的问题。就像是一个空白文档。
在打印函数中:
public void PrintFunction() {

    string outputPath = @"D:\Output\Folder\FileName.pdf";

    PrintDocument pd = new PrintDocument();
    pd.PrintPage += PrintPageHandler;

    pd.PrinterSettings.PrintToFile = true;
    pd.PrinterSettings.PrintFileName = outputPath;

    pd.PrintController = new StandardPrintController();
    pd.Print();

}

PrintPageHandler函数:(处理打印页面事件)
private void PrintPageHandler(object sender, PrintPageEventArgs e) {

     // put your contents here for printing 

    e.Graphics.DrawString("Hello World!",
                     new Font("Arial", 12),
                     Brushes.Black,
                     100,   // x-axis
                     100);  // y-axis
}

如果你想在目录不存在的情况下强制创建目录:
(将其放在outputPath的声明下面)
    string directory = Path.GetDirectoryName(outputPath);
    if (!Directory.Exists(directory))
    {
        Directory.CreateDirectory(directory);
    }

-1

您可以通过使用PrintOut方法并指定第四个输出文件名参数来打印到Windows 10 PDF打印机,如下例所示:

/// <summary>
/// Convert a file to PDF using office _Document object
/// </summary>
/// <param name="InputFile">Full path and filename with extension of the file you want to convert from</param>
/// <returns></returns>
public void PrintFile(string InputFile)
{
    // convert input filename to new pdf name
    object OutputFileName = Path.Combine(
        Path.GetDirectoryName(InputFile),
        Path.GetFileNameWithoutExtension(InputFile)+".pdf"
    );


    // Set an object so there is less typing for values not needed
    object missing = System.Reflection.Missing.Value;

    // `doc` is of type `_Document`
    doc.PrintOut(
        ref missing,    // Background
        ref missing,    // Append
        ref missing,    // Range
        OutputFileName, // OutputFileName
        ref missing,    // From
        ref missing,    // To
        ref missing,    // Item
        ref missing,    // Copies
        ref missing,    // Pages
        ref missing,    // PageType
        ref missing,    // PrintToFile
        ref missing,    // Collate
        ref missing,    // ActivePrinterMacGX
        ref missing,    // ManualDuplexPrint
        ref missing,    // PrintZoomColumn
        ref missing,    // PrintZoomRow
        ref missing,    // PrintZoomPaperWidth
        ref missing,    // PrintZoomPaperHeight
    );
}

OutputFile 是您想要转换的输入文档的完整路径字符串,而 doc 则是一个常规文档对象。有关 _Document.PrintOut() 的更多信息,请参见以下 MSDN 链接:

在示例中,PrintOut 会静默打印,当您通过指定的 inputFile 打印到 OutputFileName 时,它将被放置在与原始文档相同的文件夹中,但它将以 PDF 格式呈现,并带有 .pdf 扩展名。


9
问题中没有任何迹象表明发帖人正在使用Office产品。 - Ken White
3
@SanuelJackson:我并没有提到链接或你的修改。我的观点是,整个回答都基于一个前提,即问题提出者正在使用Word、Excel或自动化工具,而问题中没有任何迹象表明这是事实。 - Ken White
1
@KenWhite - 是的,我注意到了。我刚刚发布了一个解决方案,因为我正好在这个领域 :) 。我还清理了一下,因为答案中并不清楚它是一个非Office问题的Office解决方案。由于它仍然与C#相关,并且确实有效,所以感觉可以保留,但需要一些努力来清理它并使其清晰明了地适用于Office。 :) - Kraang Prime
1
Microsoft.Office.Tools.Word.Document.PrintOut https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.tools.word.document.printout?view=vsto-2017 - Stefan Steiger
2
错失重点的答案只是垃圾,因此绝对没有用处。相反地,我正在寻找一个非常具体的问题,而人们回答不同的问题却使问题变得更加困难,例如:哦,你试过这个 DLL 或那个库吗?你也可以使用另一种语言! - Xan-Kun Clark-Davis
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接