Matthias_70
Matthias_70

Reputation: 111

Programmatically set filename and path in Microsoft Print to PDF printer

I have a C# .net program that creates various documents. These documents should be stored in different locations and with different, clearly defined names.

To do so, I use the System.Drawing.Printing.PrintDocument class. I select the Microsoft Print to PDF as printer with this statement:

PrintDocument.PrinterSettings.PrinterName = "Microsoft Print to PDF";

While doing so I'm able to print my document in a pdf file. The user gets a file select dialog. He can then specify in this dialog box the name of the pdf file and where to store it.

As the amount of files are large and it is annoying and error-prone to find always the correct path and name, I would like to set the correct path and filename in this dialog box programmatically.

I have already tested these attributes:

PrintDocument.PrinterSettings.PrintFileName PrintDocument.DocumentName

Writing the required path and filename to these attributes didn't help. Does anybody know, how to set the default values for path and filename for the Microsoft Print to PDF printer in C#?

Note: My environment : Windows 10, Visual Studio 2010, .net framework 4.5

Upvotes: 11

Views: 35938

Answers (4)

ACurti
ACurti

Reputation: 1

Today I found out I must have some kind of undiagnosed mental problem. I was obsessed with doing something completely unimportant for no good reason, and it works!

Tested on VS 2010, appreciate if anyone who uses it share if it works on your VS version.

private void changePrintPreviewDialogButton(PrintPreviewDialog printPrvDlg, String fullFilePath)
{
    // Find the print button in the PrintPreviewDialog and replace it with ours
    Control.ControlCollection cc = (printPrvDlg as Form).Controls;
    foreach (Control ctrl in cc)
    {
        // Find the toolStrip where the button should be
        if (ctrl.Name == "toolStrip1")
        {
            ToolStrip ts = (ToolStrip)ctrl;
            foreach (ToolStripItem tsi in ts.Items)
            {
                // Find the print button it self
                if (tsi.Name == "printToolStripButton")
                {
                    // Replace the old button with a our new customized one
                    ToolStripButton newTsi =
                        new ToolStripButton(
                            "", // No text, or it appears after the image
                            tsi.Image,
                            new EventHandler((Object sender, EventArgs e) => 
                            {
                                // Create our customized save dialog
                                SaveFileDialog sfd = new SaveFileDialog();
                                sfd.Title = "Save Print Output As";
                                sfd.InitialDirectory = Path.GetDirectoryName(fullFilePath);
                                sfd.FileName = Path.GetFileNameWithoutExtension(fullFilePath) + ".pdf";
                                sfd.Filter = "PDF File(*.pdf)|*.pdf";
                                
                                if (sfd.ShowDialog(printPrvDlg) == DialogResult.OK)
                                {
                                    printPrvDlg.Document.PrinterSettings.PrintFileName = sfd.FileName;
                                    printPrvDlg.Document.PrinterSettings.PrintToFile = true;

                                    // Perform a click in the original button
                                    ((ToolStripButton)(sender as ToolStripButton).Tag).PerformClick();
                                }
                            }),
                            tsi.Name);
                    newTsi.ToolTipText = tsi.ToolTipText;
                    newTsi.Tag = tsi; // Keep the original button to call latter

                    ts.Items.Remove(tsi);
                    ts.Items.Insert(0, newTsi);

                    return;
                }
            }
        }
    }
}

//Context for using it
private void configPrinterPreview()
{
    PrintDocument pd = new PrintDocument();
    pd.DefaultPageSettings.Landscape = false;
    pd.DocumentName = Path.GetFileNameWithoutExtension(file) + ".pdf";
    pd.PrinterSettings.PrinterName = "Microsoft Print to PDF";
    pd.PrintPage += new PrintPageEventHandler(this.PrintPage);

    PrintPreviewDialog printPrvDlg = new PrintPreviewDialog();
    printPrvDlg.Document = pd;
    printPrvDlg.ShowIcon = true;
    printPrvDlg.Icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location);
    printPrvDlg.Width = parentForm.Width;
    printPrvDlg.Height = parentForm.Height;
    (printPrvDlg as Form).WindowState = FormWindowState.Maximized;
    changePrintPreviewDialogButton(printPrvDlg, file);
    printPrvDlg.ShowDialog(parentForm);
}

Upvotes: 0

SherrillL
SherrillL

Reputation: 125

As noted in other answers, you can force PrinterSettings.PrintToFile = true, and set the PrinterSettings.PrintFileName, but then your user doesn't get the save as popup. My solution is to go ahead and show the Save As dialog myself, populating that with my "suggested" filename [in my case, a text file (.txt) which I change to .pdf], then set the PrintFileName to the result.

DialogResult userResp = printDialog.ShowDialog();
if (userResp == DialogResult.OK)
{
    if (printDialog.PrinterSettings.PrinterName == "Microsoft Print to PDF")
    {   // force a reasonable filename
        string basename = Path.GetFileNameWithoutExtension(myFileName);
        string directory = Path.GetDirectoryName(myFileName);
        prtDoc.PrinterSettings.PrintToFile = true;
        // confirm the user wants to use that name
        SaveFileDialog pdfSaveDialog = new SaveFileDialog();
        pdfSaveDialog.InitialDirectory = directory;
        pdfSaveDialog.FileName = basename + ".pdf";
        pdfSaveDialog.Filter = "PDF File|*.pdf";
        userResp = pdfSaveDialog.ShowDialog();
        if (userResp != DialogResult.Cancel)
            prtDoc.PrinterSettings.PrintFileName = pdfSaveDialog.FileName;
    }

    if (userResp != DialogResult.Cancel)  // in case they canceled the save as dialog
    {
        prtDoc.Print();
    }
}

Upvotes: 5

JRB
JRB

Reputation: 2131

I did some experimenting myself but like yourself was also not able to prefill the SaveAs dialog in the PrintDialog with the DocumentName or PrinterSettings.PrintFileName already filled in the PrintDocument instance. This seems counterintuitive, so maybe I'm missing something

If you want to, you can however bypass the printdialog and print automatically without any user interaction at all. If you choose to do so, you must make sure beforehand that the directory to which you want to add a document to is in existence and that the document to be added is not in existence.

string existingPathName = @"C:\Users\UserName\Documents";
string notExistingFileName = @"C:\Users\UserName\Documents\TestPrinting1.pdf";

if (Directory.Exists(existingPathName) && !File.Exists(notExistingFileName))
{
    PrintDocument pdoc = new PrintDocument();
    pdoc.PrinterSettings.PrinterName = "Microsoft Print to PDF";
    pdoc.PrinterSettings.PrintFileName = notExistingFileName;
    pdoc.PrinterSettings.PrintToFile = true;
    pdoc.PrintPage += pdoc_PrintPage;
    pdoc.Print();
 }

Upvotes: 4

TDull
TDull

Reputation: 818

It seems like the PrintFilename is ignored if the PrintToFile property is not set to true. If PrintToFile is set to true and a valid filename (full path) is provided, the filedialog where the user selects filename will not be displayed.

Tip: When setting the printername of the printersettings you can check the IsValid property to check that this printer actually exists. For more info on printersettings and finding installed printers check this post

Upvotes: 1

Related Questions