1

I have the following code which prints text file from C# to printer its based on the this article it prints plain text perfect but when I try to print .docx and .pdf file it prints but convert the content to some-kind of encoded characters. How can I fix this to print pdf and doc file?

private void btnPrint_Click(object sender, EventArgs e)
{
    // Select the desired printer. ps.Duplex = Duplex.Simplex; // This works
    pdocFile.PrinterSettings.PrinterName = cboPrinter.Text;
    pdocFile.PrinterSettings.Duplex =  Duplex.Horizontal;
    // Print the checked files.
    foreach (string filename in clbFiles.CheckedItems)
    {
        Console.WriteLine("Printing: " + filename);

        // Get the file's name without the path.
        FileInfo file_into = new FileInfo(filename);
        string short_name = file_into.Name;

        // Set the PrintDocument's name for use by the printer queue.
        pdocFile.DocumentName = short_name;

        // Read the file's contents.
        try
        {
            FileContents = File.ReadAllText(filename).Trim();
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error reading file " + filename +
                    ".\n" + ex.Message);
            return;
        }

        // Print.
        pdocFile.Print();
    }

    MessageBox.Show("Spooled " + clbFiles.CheckedItems.Count +
            " files for printing.");
    }

//

private string FileContents;

// Print a page of the text file.
private void pdocTextFile_PrintPage(object sender, PrintPageEventArgs e)
{
    // Make a font for printing.
    using (Font font = new Font("Courier New", 10))
    {
        // Make a StringFormat to align text normally.
        using (StringFormat string_format = new StringFormat())
        {
            // See how much of the remaining text will fit.
            SizeF layout_area = new SizeF(e.MarginBounds.Width, e.MarginBounds.Height);
            int chars_fitted, lines_filled;
            e.Graphics.MeasureString(FileContents, font,
            layout_area, string_format,
            out chars_fitted, out lines_filled);

            // Print as much as will fit.
            e.Graphics.DrawString(
            FileContents.Substring(0, chars_fitted),
            font, Brushes.Black, e.MarginBounds,
            string_format);

            // Remove the printed text from the string.
            FileContents = FileContents.Substring(chars_fitted).Trim();
        }
    }

    // See if we are done.
    e.HasMorePages = FileContents.Length > 0;
}

see Image link below

enter image description here

Sibeesh Venu
  • 18,755
  • 12
  • 103
  • 140
afri
  • 49
  • 2
  • 12
  • 2
    Your code tries to handle PDF and DOCX files as if they're text. They're not. They have binary content. You can't pretend otherwise. – Ken White Dec 26 '16 at 05:15
  • 1
    Possible duplicate of [How can I send a file document to the printer and have it print?](http://stackoverflow.com/questions/6103705/how-can-i-send-a-file-document-to-the-printer-and-have-it-print) and http://stackoverflow.com/q/17448465/62576 – Ken White Dec 26 '16 at 05:16
  • @KenWhite i already tried that but i kept getting `Additional information: No application is associated with the specified file for this operation` – afri Dec 26 '16 at 05:22
  • 2
    If there is no application associated with them on the computer, you can't print them unless you're prepared to write interpreters for those file types yourself (IOW, parse the file, convert it to the proper low-level printer commands, and send those commands to the printer). – Ken White Dec 26 '16 at 05:29

1 Answers1

0

Your example above is taking a binary file format and trying to print it using a method that uses plain text, which will not work. You have a few options on how you could approach this.

  1. Some printers allow you to submit various file types directly to them over a protocol like FTP. And example of this can be seen here. This method works great in enterprise environments which have business printers but is limited to the file types supported by each printer, and each printer's unique requirements.
  2. For some formats, you can use third-party libraries like iText in your C# code to handle the actual printing. This option gives you a ton of control over the formatting, with the overhead of having to maintain additional code for every file type you wish to support.
  3. You can also use the example code posted here to utilize already installed applications. In this example, it takes advantage of the Print verb made available by Adobe Acrobat, Word, etc. You'll need to make sure the applications have their defaults and surface the correct verb (which typically correlates with the context menu when right-clicking on a file name). This method is probably the most straight-forward option to handle files as-is.
Community
  • 1
  • 1
Anthony Mattas
  • 271
  • 1
  • 12
  • @afri correct, your are using code for non-binary data to handle binary data which won't work. I'm suggesting if your printer supports this functionality just send the files directly to the printer. – Anthony Mattas Dec 26 '16 at 05:24
  • @afri another option would be to do something like this http://stackoverflow.com/questions/6103705/how-can-i-send-a-file-document-to-the-printer-and-have-it-print – Anthony Mattas Dec 26 '16 at 05:24
  • I does print PDF and DOCX but the problems is it prints encrypted text instead of printing the document content same on Cannon MX470 and Microsoft Print to PDF – afri Dec 26 '16 at 05:25
  • Thanks Anthony i already tried that but i kept getting `Additional information: No application is associated with the specified file for this operation` on `p.Start();` – afri Dec 26 '16 at 05:26
  • Do you have Adobe Acrobat installed? – Anthony Mattas Dec 26 '16 at 05:27
  • yes its under `C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe` – afri Dec 26 '16 at 05:27
  • Does it have its defaults? If it doesn't the Print verb won't be available. – Anthony Mattas Dec 26 '16 at 05:34
  • the reader was corrupted i installed Adobe acrobat DC and i am able to see the content now i am trying to incorporated the snippet to my application. Question So all i have to add is this `Process p = new Process(); p.StartInfo = info; p.Start();` code to `btnPrint_click` event right? – afri Dec 26 '16 at 05:39
  • `//Class containing information on the process you want to start. ProcessStartInfo info = new ProcessStartInfo(); //What "Verb" you want to use, typicially matches what you see in the right click menu info.Verb = "print"; //The process you want to invoke, by using your file name it'll invoke the handler for that file type using the Verb you specified above.. i.e. Acrobat info.FileName = @"c:\output.pdf"; //Tries to not open a window info.CreateNoWindow = true; info.WindowStyle = ProcessWindowStyle.Hidden;` – Anthony Mattas Dec 26 '16 at 05:47
  • Work like a charm. Thank you so much. Can you update the answer? – afri Dec 26 '16 at 06:00
  • Anthony, Last question How can i apply Duplex? I added `pdocFile.PrinterSettings.Duplex = Duplex.Horizontal;` above the `foreach()` its not working and I am not sure its not working on one the printers on the network – afri Dec 28 '16 at 03:22