Click here to Skip to main content
15,887,746 members
Articles / Productivity Apps and Services / Microsoft Office
Article

Printing Word Documents in C#

Rate me:
Please Sign up or sign in to vote.
3.63/5 (25 votes)
15 Jul 2005CPOL 171.6K   27   18
Printing documents using Microsoft Word and C#

Introduction

I feel I need to share this pain. I have been struggling for days now to get something simple to work for me. That is to print out a Word document (RTF format) to a printer using Word. It also has to work with multiple versions of Word (so far 2000 and 2003). I thought I would share everything that I have learnt.

If you want this to work for multiple versions, install the earliest version of Word and Add Reference to its COM component and develop against these.

Next to the code...

The Code

C#
// Create an Application object
Word.ApplicationClass ac = new Word.ApplicationClass();
Word.Application app = ac.Application;

// I'm setting all of the alerts to be off as I am trying to get
// this to print in the background
app.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;

// Open the document to print...
object filename = "myFile.rtf";
object missingValue = Type.Type.Missing;

// Using OpenOld so as to be compatible with other versions of Word
Word.Document document = app.Documents.OpenOld(ref filename,
ref missingValue, ref missingValue, 
ref missingValue, ref missingValue, ref missingValue, 
	ref missingValue, ref missingValue, ref missingValue, ref missingValue);

// Set the active printer
app.ActivePrinter = "My Printer Name";

object myTrue = true; // Print in background
object myFalse = false;

// Using PrintOutOld to be version independent
m_App.ActiveDocument.PrintOutOld(ref myTrue, 
ref myFalse, ref missingValue, ref missingValue, ref missingValue, 
	missingValue, ref missingValue, 
ref missingValue, ref missingValue, ref missingValue, ref myFalse, 
	ref missingValue, ref missingValue, ref m_MissingValue);

document.Close(ref missingValue, ref missingValue, ref missingValue);

// Make sure all of the documents are gone from the queue
while(m_App.BackgroundPrintingStatus > 0)
{
System.Threading.Thread.Sleep(250);
}

app.Quitref missingValue, ref missingValue, ref missingValue);

I do not claim that this is perfect, but it's as good as I can get. It works on my machine anyway.

History

  • 15th July, 2005: Initial post 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionsolution for printing of all files. Pin
nsk_saravana7-Dec-11 2:01
nsk_saravana7-Dec-11 2:01 
Imports System.IO
Imports System.Drawing.Printing
Imports MODI
Imports DocumentProcessing
'Imports Microsoft.Office.Interop.Word
Imports Microsoft.Office.Core
Imports System.Runtime.InteropServices

Imports PrinterQueueWatch
Public Class Form1

Private printFont As Font
Private streamToPrint As StreamReader
Private Shared filePath As String
Private _MODIDocument As MODI.Document = Nothing
Dim Proc As New System.Diagnostics.Process



Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

filePath = "E:\Personal\Personal\BackButtonDisable.txt"
'Printing()

'PrintDialog1.PrinterSettings.PrintFileName = filePath

'PrintDialog1.Document = PrintDocument1
'PrintDialog1.ShowDialog()
'PrintFile()
printdoc()
'PrintMyExcelFile()
'PrintPDF("E:\Personal\Personal\Credit Card\PNR IOHPTI\frmViewPassportPage1.pdf")

End Sub


'Print the file.
Public Sub Printing()
Try
streamToPrint = New StreamReader(filePath)
Try
printFont = New Font("Arial", 10)
Dim pd As New PrintDocument()
AddHandler pd.PrintPage, AddressOf pd_PrintPage
'Print the document.
pd.Print()
Finally
streamToPrint.Close()
End Try
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub 'Printing

Private Sub pd_PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
Dim linesPerPage As Single = 0
Dim yPos As Single = 0
Dim count As Integer = 0
Dim leftMargin As Single = ev.MarginBounds.Left
Dim topMargin As Single = ev.MarginBounds.Top
Dim line As String = Nothing



' Calculate the number of lines per page.
linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics)

' Print each line of the file.
While count < linesPerPage
line = streamToPrint.ReadLine()
If line Is Nothing Then
Exit While
End If
yPos = topMargin + count * printFont.GetHeight(ev.Graphics)
ev.Graphics.DrawString(line, printFont, Brushes.Black, leftMargin, yPos, New StringFormat())
count += 1
End While

' If more lines exist, print another page.
If (line IsNot Nothing) Then
ev.HasMorePages = True
Else
ev.HasMorePages = False
End If
End Sub





'Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage

' 'Dim linesPerPage As Single = 0
' 'Dim yPos As Single = 0
' 'Dim count As Integer = 0
' 'Dim leftMargin As Single = e.MarginBounds.Left
' 'Dim topMargin As Single = e.MarginBounds.Top
' 'Dim line As String = Nothing

' '' Calculate the number of lines per page.
' 'linesPerPage = e.MarginBounds.Height / printFont.GetHeight(e.Graphics)

' '' Iterate over the file, printing each line.
' 'While count < linesPerPage
' ' line = streamToPrint.ReadLine()
' ' If line Is Nothing Then
' ' Exit While
' ' End If
' ' yPos = topMargin + count * printFont.GetHeight(e.Graphics)
' ' e.Graphics.DrawString(line, printFont, Brushes.Black, leftMargin, _
' ' yPos, New StringFormat())
' ' count += 1
' 'End While

' '' If more lines exist, print another page.
' 'If Not (line Is Nothing) Then
' ' e.HasMorePages = True
' 'Else
' ' e.HasMorePages = False
' 'End If
' Dim Image As System.Drawing.Image = pictureBox1.Image
' e.Graphics.DrawImage(Image, New Point(0, 0))


'End Sub

Private Sub PrintFile()
'_filename = filename;
_MODIDocument = New MODI.Document()

_MODIDocument.Create("E:\Personal\Personal\Medical\Saravana_Nov_Activities.doc")
If _MODIDocument IsNot Nothing Then
Dim d As New PrintDialog()
d.AllowSomePages = True
d.AllowSelection = False
d.PrintToFile = False
Dim ps As New PrinterSettings()
ps.MinimumPage = 0
ps.MaximumPage = _MODIDocument.Images.Count - 1
ps.FromPage = 0
ps.ToPage = _MODIDocument.Images.Count - 1

d.PrinterSettings = ps
If d.ShowDialog() = DialogResult.OK Then

_MODIDocument.PrintOut(d.PrinterSettings.FromPage, d.PrinterSettings.ToPage, d.PrinterSettings.Copies, d.PrinterSettings.PrinterName, "", False, _
MODI.MiPRINT_FITMODES.miPRINT_ACTUALSIZE)
End If
End If
End Sub


Public Sub printdoc()

Dim ac As New Microsoft.Office.Interop.Word.Application

Dim app As Microsoft.Office.Interop.Word.Application = ac.Application
Dim lsPriterName As String
' I'm setting all of the alerts to be off as I am trying to get
' this to print in the background
app.DisplayAlerts = Microsoft.Office.Interop.Word.WdAlertLevel.wdAlertsNone

' Open the document to print...
Dim filename As Object = "E:\Personal\Personal\Medical\Saravana_Nov_Activities.docx"
Dim missingValue As Object = Type.Missing
' Using OpenOld so as to be compatible with other versions of Word
Dim document As Microsoft.Office.Interop.Word.Document = app.Documents.Open(filename, missingValue, missingValue, missingValue, missingValue, missingValue, _
missingValue, missingValue, missingValue, missingValue)

' Set the active printer
Dim d As New PrintDialog()
If d.ShowDialog() = DialogResult.OK Then
lsPriterName = d.PrinterSettings.PrinterName
Else
Exit Sub
End If

app.ActivePrinter = lsPriterName
Dim myTrue As Object = True
' Print in background
Dim myFalse As Object = False
' Using PrintOutOld to be version independent
app.ActiveDocument.PrintOut(myTrue, myFalse, missingValue, missingValue, missingValue, missingValue, _
missingValue, missingValue, missingValue, missingValue, myFalse, missingValue, _
missingValue, missingValue)

document.Close(missingValue, missingValue, missingValue)

' Make sure all of the documents are gone from the queue
While app.BackgroundPrintingStatus > 0
System.Threading.Thread.Sleep(250)
End While

' Cleanup:
GC.Collect()
GC.WaitForPendingFinalizers()
Marshal.FinalReleaseComObject(app)
Marshal.FinalReleaseComObject(ac)
document = Nothing

End Sub

'Private Sub InvokePrint(ByVal sender As Object, ByVal e As RoutedEventArgs)
' ' Create the print dialog object and set options
' Dim pDialog As New PrintDialog()
' pDialog.PageRangeSelection = PageRangeSelection.AllPages
' pDialog.UserPageRangeEnabled = True
' ' Display the dialog. This returns true if the user presses the Print button.
' Dim print As Nullable(Of [Boolean]) = pDialog.ShowDialog()
' If print = True Then
' Dim xpsDocument As New XpsDocument("C:\FixedDocumentSequence.xps", FileAccess.ReadWrite)
' Dim fixedDocSeq As FixedDocumentSequence = xpsDocument.GetFixedDocumentSequence()
' pDialog.PrintDocument(fixedDocSeq.DocumentPaginator, "Test print job")
' End If
'End Sub

Private Sub PrintMyExcelFile()
Dim excelApp As New Microsoft.Office.Interop.Excel.Application()
' Open the Workbook:
Dim wb As Microsoft.Office.Interop.Excel.Workbook = excelApp.Workbooks.Open("E:\Personal\Personal\Medical\Card.xlsx", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, _
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, _
Type.Missing, Type.Missing, Type.Missing)
' Get the first worksheet.
' (Excel uses base 1 indexing, not base 0.)
Dim ws As Microsoft.Office.Interop.Excel.Worksheet = DirectCast(wb.Worksheets(1), Microsoft.Office.Interop.Excel.Worksheet)
' Print out 1 copy to the default printer:


'Dim app As Microsoft.Office.Interop.Excel.Application = excelApp.Application
'Dim lsPriterName As String
'Dim d As New PrintDialog()
'If d.ShowDialog() = DialogResult.OK Then
' lsPriterName = d.PrinterSettings.PrinterName
'Else
' Exit Sub
'End If

'ws.ActivePrinter = lsPriterName

'ws.ActiveDocument.PrintOutOld(Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, _
' Type.Missing, Type.Missing)
ws.PrintOut(Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, _
Type.Missing, Type.Missing)
' Cleanup:
GC.Collect()
GC.WaitForPendingFinalizers()
Marshal.FinalReleaseComObject(ws)
wb.Close(False, Type.Missing, Type.Missing)
Marshal.FinalReleaseComObject(wb)
excelApp.Quit()
Marshal.FinalReleaseComObject(excelApp)
End Sub

Public Function PrintPDF(ByVal PDFFile As String, ByVal PrinterName As String, ByVal Timeout As Integer) As Integer

Dim d As New PrintDialog()
If d.ShowDialog() = DialogResult.OK Then
PrinterName = d.PrinterSettings.PrinterName
Else
Exit Function
End If

If PrinterName.Trim.Length = 0 Then
PrinterName = (New System.Drawing.Printing.PrinterSettings).PrinterName
End If

' Dim Proc As New System.Diagnostics.Process

Proc.EnableRaisingEvents = True
Proc.StartInfo.FileName = PDFFile
Proc.StartInfo.Arguments = Chr(34) + PrinterName + Chr(34)
Proc.StartInfo.Verb = "PrintTo"
Proc.StartInfo.WindowStyle = ProcessWindowStyle.Minimized
Proc.StartInfo.CreateNoWindow = True

' Now start monitoring the printer's queue.
Dim Monitor As New PrinterQueueWatch.PrinterMonitorComponent
Monitor.MonitorJobAddedEvent = False
Monitor.MonitorJobDeletedEvent = False
Monitor.MonitorJobSetEvent = True
Monitor.MonitorJobWrittenEvent = False
Monitor.MonitorPrinterChangeEvent = False
AddHandler Monitor.JobSet, AddressOf SetPrintJob
Monitor.DeviceName = PrinterName

' Now that I am watching, start up Acrobat.
Proc.Start()

Do While Timeout > 0 AndAlso Not Proc.HasExited
System.Threading.Thread.Sleep(1000)
Timeout -= 1
Loop

' Stop monitoring.
RemoveHandler Monitor.JobSet, AddressOf SetPrintJob
Monitor = Nothing

If Not Proc.HasExited Then
Debug.Print("Killing process")
Proc.Kill()
End If

Debug.WriteLine("Closing process")
Proc.Close()

Return 0
End Function
Public Function PrintPDF(ByVal PDFFile As String) As Integer
Return PrintPDF(PDFFile, "", 60)
End Function
Public Function PrintPDF(ByVal PDFFile As String, ByVal Timeout As Integer) As Integer
Return PrintPDF(PDFFile, "", Timeout)
End Function

Private Sub SetPrintJob(ByVal sender As Object, ByVal e As System.EventArgs)
' Print job is set to print.
System.Threading.Thread.Sleep(500)
Proc.Kill()
End Sub

End Class
Questioncode to print xls Pin
nsk_saravana6-Dec-11 1:16
nsk_saravana6-Dec-11 1:16 
QuestionMy code in vb.net Pin
nsk_saravana5-Dec-11 21:23
nsk_saravana5-Dec-11 21:23 
GeneralMy vote of 5 Pin
vickiD15-Sep-10 19:04
vickiD15-Sep-10 19:04 
GeneralPrinting Word Document as XPS Pin
Member 248948422-Jan-09 23:24
Member 248948422-Jan-09 23:24 
GeneralThermal Printer Pin
NewbieWizDev5-Nov-08 5:21
NewbieWizDev5-Nov-08 5:21 
GeneralVery goog! Pin
Jansen2084-Sep-08 22:23
Jansen2084-Sep-08 22:23 
GeneralPrinting to PDF Pin
nano2k4-Jun-08 22:19
nano2k4-Jun-08 22:19 
GeneralRe: Printing to PDF Pin
JoshDunke11-Jun-09 5:10
JoshDunke11-Jun-09 5:10 
GeneralRe: Printing to PDF Pin
nano2k11-Jun-09 5:16
nano2k11-Jun-09 5:16 
GeneralWord assembly Pin
Cobus C29-Mar-07 0:27
Cobus C29-Mar-07 0:27 
GeneralRe: Word assembly Pin
vrumfundel29-Mar-07 23:03
vrumfundel29-Mar-07 23:03 
GeneralRe: Word assembly Pin
Cobus C30-Mar-07 1:19
Cobus C30-Mar-07 1:19 
GeneralRe: Word assembly Pin
ap_wooka2-Apr-08 10:21
ap_wooka2-Apr-08 10:21 
GeneralCorrecci&#243;n del c&#243;digo Pin
kateerre7-Oct-05 0:09
kateerre7-Oct-05 0:09 
GeneralRe: Correcci&#243;n del c&#243;digo Pin
Stephengb11-Feb-06 13:18
Stephengb11-Feb-06 13:18 
GeneralShort and good Pin
Pierfabio24-Aug-05 2:03
Pierfabio24-Aug-05 2:03 
GeneralMessage Closed Pin
12-Jul-15 21:12
Pokenderyindo12-Jul-15 21:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.