Click here to Skip to main content
15,885,979 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
Hello everyone,

I have created report with crystal report (C#, WinForm) and I want to print it on continuous stationery, which is not perforated (i.e. continuous roll of paper)

How to set printing options so that I can print on Epson Dot Matrix, with auto tear facility?

Data on report is purchase item, so there is change in number of records with each purchase,
I want to set code so that printer will print and there is no extra paper feed because of paper size...

Please help me to get through this problem...

Firdaus Shaikh.
Posted
Comments
jshhrdk 10-Oct-12 7:14am    
I want to print more than one sales invoice through crystal report.
so how to set record selection formula for continues printing? in asp.net using vb.net
Firdaus Shaikh 20-Oct-12 6:49am    
well create a new datatable, add column names like
datatable.Columns.Add("columnName1", Type.GetType("System.String"));
datatable.Columns.Add("columnName2", Type.GetType("System.String")); etc


then add datarow and add items for each column
for (int i = 0; i < datagridview.RowCount-1; i++)
{
datarow = psdatatable.NewRow();
datarow["column1"] = txtcolumn1.Text;
datarow["column1"] = txtcolumn1.Text; etc

//add datarow to datatable
datatable.Rows.Add(datarow);
}

then in form of report viewer add
ReportName cReport = new ReportName();
ReportDocument rptDocument = cReport;
rptDocument.Load("..\\CrystalReport1.rpt");
rptDocument.SetDataSource(datatable);

crystalReportViewer1.ReportSource = rptDocument;
crystalReportViewer1.Refresh();

this will display report for one invoice...

Hello Arun,
Thanks for your reply I will try this and secondly,
I have found a work around and below is the code,
main code taken from somewhere I don't remember while finding every bit of code...


this code is taken from Internet class named CustomPrintForm.cs
1) Add below class in your project
C#
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Security;
using System.ComponentModel;
using System.Drawing.Printing;

namespace CustomPrintForm
{
    /// <summary>
    /// Summary description for CustomPrintForm.
    /// </summary>
    public class CustomPrintForm
    {
        // Make a static class
        private CustomPrintForm()
        {
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct structPrinterDefaults
        {
            [MarshalAs(UnmanagedType.LPTStr)]
            public String pDatatype;
            public IntPtr pDevMode;
            [MarshalAs(UnmanagedType.I4)]
            public int DesiredAccess;
        };

        [DllImport("winspool.Drv", EntryPoint = "OpenPrinter", SetLastError = true,
             CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall),
        SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPTStr)]
			string printerName,
            out IntPtr phPrinter,
            ref structPrinterDefaults pd);

        [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true,
             CharSet = CharSet.Unicode, ExactSpelling = false,
             CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern bool ClosePrinter(IntPtr phPrinter);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct structSize
        {
            public Int32 width;
            public Int32 height;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct structRect
        {
            public Int32 left;
            public Int32 top;
            public Int32 right;
            public Int32 bottom;
        }

        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
        internal struct FormInfo1
        {
            [FieldOffset(0), MarshalAs(UnmanagedType.I4)]
            public uint Flags;
            [FieldOffset(4), MarshalAs(UnmanagedType.LPWStr)]
            public String pName;
            [FieldOffset(8)]
            public structSize Size;
            [FieldOffset(16)]
            public structRect ImageableArea;
        };

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi/* changed from CharSet=CharSet.Auto */)]
        internal struct structDevMode
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public String
                dmDeviceName;
            [MarshalAs(UnmanagedType.U2)]
            public short dmSpecVersion;
            [MarshalAs(UnmanagedType.U2)]
            public short dmDriverVersion;
            [MarshalAs(UnmanagedType.U2)]
            public short dmSize;
            [MarshalAs(UnmanagedType.U2)]
            public short dmDriverExtra;
            [MarshalAs(UnmanagedType.U4)]
            public int dmFields;
            [MarshalAs(UnmanagedType.I2)]
            public short dmOrientation;
            [MarshalAs(UnmanagedType.I2)]
            public short dmPaperSize;
            [MarshalAs(UnmanagedType.I2)]
            public short dmPaperLength;
            [MarshalAs(UnmanagedType.I2)]
            public short dmPaperWidth;
            [MarshalAs(UnmanagedType.I2)]
            public short dmScale;
            [MarshalAs(UnmanagedType.I2)]
            public short dmCopies;
            [MarshalAs(UnmanagedType.I2)]
            public short dmDefaultSource;
            [MarshalAs(UnmanagedType.I2)]
            public short dmPrintQuality;
            [MarshalAs(UnmanagedType.I2)]
            public short dmColor;
            [MarshalAs(UnmanagedType.I2)]
            public short dmDuplex;
            [MarshalAs(UnmanagedType.I2)]
            public short dmYResolution;
            [MarshalAs(UnmanagedType.I2)]
            public short dmTTOption;
            [MarshalAs(UnmanagedType.I2)]
            public short dmCollate;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public String dmFormName;
            [MarshalAs(UnmanagedType.U2)]
            public short dmLogPixels;
            [MarshalAs(UnmanagedType.U4)]
            public int dmBitsPerPel;
            [MarshalAs(UnmanagedType.U4)]
            public int dmPelsWidth;
            [MarshalAs(UnmanagedType.U4)]
            public int dmPelsHeight;
            [MarshalAs(UnmanagedType.U4)]
            public int dmNup;
            [MarshalAs(UnmanagedType.U4)]
            public int dmDisplayFrequency;
            [MarshalAs(UnmanagedType.U4)]
            public int dmICMMethod;
            [MarshalAs(UnmanagedType.U4)]
            public int dmICMIntent;
            [MarshalAs(UnmanagedType.U4)]
            public int dmMediaType;
            [MarshalAs(UnmanagedType.U4)]
            public int dmDitherType;
            [MarshalAs(UnmanagedType.U4)]
            public int dmReserved1;
            [MarshalAs(UnmanagedType.U4)]
            public int dmReserved2;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct PRINTER_INFO_9
        {
            public IntPtr pDevMode;
        }

        [DllImport("winspool.Drv", EntryPoint = "AddFormW", SetLastError = true,
             CharSet = CharSet.Unicode, ExactSpelling = true,
             CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern bool AddForm(
         IntPtr phPrinter,
            [MarshalAs(UnmanagedType.I4)] int level,
         ref FormInfo1 form);

        /*    This method is not used
                [DllImport("winspool.Drv", EntryPoint="SetForm", SetLastError=true,
                     CharSet=CharSet.Unicode, ExactSpelling=false,
                     CallingConvention=CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
                internal static extern bool SetForm(IntPtr phPrinter, string paperName,
                    [MarshalAs(UnmanagedType.I4)] int level, ref FormInfo1 form);
        */
        [DllImport("winspool.Drv", EntryPoint = "DeleteForm", SetLastError = true,
             CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall),
        SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern bool DeleteForm(
         IntPtr phPrinter,
            [MarshalAs(UnmanagedType.LPTStr)] string pName);

        [DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false,
             ExactSpelling = true, CallingConvention = CallingConvention.StdCall),
        SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern Int32 GetLastError();

        [DllImport("GDI32.dll", EntryPoint = "CreateDC", SetLastError = true,
             CharSet = CharSet.Unicode, ExactSpelling = false,
             CallingConvention = CallingConvention.StdCall),
        SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern IntPtr CreateDC([MarshalAs(UnmanagedType.LPTStr)]
			string pDrive,
            [MarshalAs(UnmanagedType.LPTStr)] string pName,
            [MarshalAs(UnmanagedType.LPTStr)] string pOutput,
            ref structDevMode pDevMode);

        [DllImport("GDI32.dll", EntryPoint = "ResetDC", SetLastError = true,
             CharSet = CharSet.Unicode, ExactSpelling = false,
             CallingConvention = CallingConvention.StdCall),
        SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern IntPtr ResetDC(
         IntPtr hDC,
         ref structDevMode
            pDevMode);

        [DllImport("GDI32.dll", EntryPoint = "DeleteDC", SetLastError = true,
             CharSet = CharSet.Unicode, ExactSpelling = false,
             CallingConvention = CallingConvention.StdCall),
        SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern bool DeleteDC(IntPtr hDC);

        [DllImport("winspool.Drv", EntryPoint = "SetPrinterA", SetLastError = true,
            CharSet = CharSet.Auto, ExactSpelling = true,
            CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern bool SetPrinter(
           IntPtr hPrinter,
           [MarshalAs(UnmanagedType.I4)] int level,
           IntPtr pPrinter,
           [MarshalAs(UnmanagedType.I4)] int command);

        /*
         LONG DocumentProperties(
           HWND hWnd,               // handle to parent window 
           HANDLE hPrinter,         // handle to printer object
           LPTSTR pDeviceName,      // device name
           PDEVMODE pDevModeOutput, // modified device mode
           PDEVMODE pDevModeInput,  // original device mode
           DWORD fMode              // mode options
           );
         */
        [DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesA", SetLastError = true,
        ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern int DocumentProperties(
           IntPtr hwnd,
           IntPtr hPrinter,
           [MarshalAs(UnmanagedType.LPStr)] string pDeviceName /* changed from String to string */,
           IntPtr pDevModeOutput,
           IntPtr pDevModeInput,
           int fMode
           );

        [DllImport("winspool.Drv", EntryPoint = "GetPrinterA", SetLastError = true,
        ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool GetPrinter(
           IntPtr hPrinter,
           int dwLevel /* changed type from Int32 */,
           IntPtr pPrinter,
           int dwBuf /* chagned from Int32*/,
           out int dwNeeded /* changed from Int32*/
           );

        // SendMessageTimeout tools
        [Flags]
        public enum SendMessageTimeoutFlags : uint
        {
            SMTO_NORMAL = 0x0000,
            SMTO_BLOCK = 0x0001,
            SMTO_ABORTIFHUNG = 0x0002,
            SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
        }
        const int WM_SETTINGCHANGE = 0x001A;
        const int HWND_BROADCAST = 0xffff;

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessageTimeout(
           IntPtr windowHandle,
           uint Msg,
           IntPtr wParam,
           IntPtr lParam,
           SendMessageTimeoutFlags flags,
           uint timeout,
           out IntPtr result
           );

        public static void Add80MmPaperSizeToDefaultPrinter()
        {
            AddCustomPaperSizeToDefaultPrinter(" 80mm * Receipt Length", 80.1f, 4003.9f);
        }

        public static void Add104MmPaperSizeToDefaultPrinter()
        {
            AddCustomPaperSizeToDefaultPrinter(" 104mm * Receipt Length", 104.1f, 4003.9f);
        }

        /// <summary>
        /// Adds the printer form to the default printer
        /// </summary>
        /// <param name="paperName">Name of the printer form</param>
        /// <param name="widthMm">Width given in millimeters</param>
        /// <param name="heightMm">Height given in millimeters</param>
        public static void AddCustomPaperSizeToDefaultPrinter(string paperName, float widthMm, float heightMm)
        {
            PrintDocument pd = new PrintDocument();
            string sPrinterName = pd.PrinterSettings.PrinterName;
            AddCustomPaperSize(sPrinterName, paperName, widthMm, heightMm);
        }

        /// <summary>
        /// Add the printer form to a printer 
        /// </summary>
        /// <param name="printerName">The printer name</param>
        /// <param name="paperName">Name of the printer form</param>
        /// <param name="widthMm">Width given in millimeters</param>
        /// <param name="heightMm">Height given in millimeters</param>
        public static void AddCustomPaperSize(string printerName, string paperName, float
            widthMm, float heightMm)
        {
            if (PlatformID.Win32NT == Environment.OSVersion.Platform)
            {
                // The code to add a custom paper size is different for Windows NT then it is
                // for previous versions of windows

                const int PRINTER_ACCESS_USE = 0x00000008;
                const int PRINTER_ACCESS_ADMINISTER = 0x00000004;
                const int FORM_PRINTER = 0x00000002;

                structPrinterDefaults defaults = new structPrinterDefaults();
                defaults.pDatatype = null;
                defaults.pDevMode = IntPtr.Zero;
                defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE;
                
                IntPtr hPrinter = IntPtr.Zero;

                // Open the printer.
                if (OpenPrinter(printerName, out hPrinter, ref defaults))
                {
                    try
                    {
                        // delete the form incase it already exists
                        DeleteForm(hPrinter, paperName);
                        // create and initialize the FORM_INFO_1 structure
                        FormInfo1 formInfo = new FormInfo1();
                        formInfo.Flags = 0;
                        formInfo.pName = paperName;
                        // all sizes in 1000ths of millimeters
                        
                        formInfo.Size.width = (int)(widthMm * 1000.0);
                        formInfo.Size.height = (int)(heightMm * 1000.0);
                        formInfo.ImageableArea.left = 0;
                        formInfo.ImageableArea.right = formInfo.Size.width;
                        formInfo.ImageableArea.top = 0;
                        formInfo.ImageableArea.bottom = formInfo.Size.height;
                        if (!AddForm(hPrinter, 1, ref formInfo))
                        {
                            StringBuilder strBuilder = new StringBuilder();
                            strBuilder.AppendFormat("Failed to add the custom paper size {0} to the printer {1}, System error number: {2}",
                                paperName, printerName, GetLastError());
                            throw new ApplicationException(strBuilder.ToString());
                        }

                        // INIT
                        const int DM_OUT_BUFFER = 2;
                        const int DM_IN_BUFFER = 8;
                        structDevMode devMode = new structDevMode();
                        IntPtr hPrinterInfo, hDummy;
                        PRINTER_INFO_9 printerInfo;
                        printerInfo.pDevMode = IntPtr.Zero;
                        int iPrinterInfoSize, iDummyInt;


                        // GET THE SIZE OF THE DEV_MODE BUFFER
                        int iDevModeSize = DocumentProperties(IntPtr.Zero, hPrinter, printerName, IntPtr.Zero, IntPtr.Zero, 0);

                        if (iDevModeSize < 0)
                            throw new ApplicationException("Cannot get the size of the DEVMODE structure.");

                        // ALLOCATE THE BUFFER
                        IntPtr hDevMode = Marshal.AllocCoTaskMem(iDevModeSize + 100);

                        // GET A POINTER TO THE DEV_MODE BUFFER 
                        int iRet = DocumentProperties(IntPtr.Zero, hPrinter, printerName, hDevMode, IntPtr.Zero, DM_OUT_BUFFER);

                        if (iRet < 0)
                            throw new ApplicationException("Cannot get the DEVMODE structure.");

                        // FILL THE DEV_MODE STRUCTURE
                        devMode = (structDevMode)Marshal.PtrToStructure(hDevMode, devMode.GetType());

                        // SET THE FORM NAME FIELDS TO INDICATE THAT THIS FIELD WILL BE MODIFIED
                        devMode.dmFields = 0x10000; // DM_FORMNAME 
                        // SET THE FORM NAME
                        devMode.dmFormName = paperName;

                        // PUT THE DEV_MODE STRUCTURE BACK INTO THE POINTER
                        Marshal.StructureToPtr(devMode, hDevMode, true);

                        // MERGE THE NEW CHAGES WITH THE OLD
                        iRet = DocumentProperties(IntPtr.Zero, hPrinter, printerName,
                                 printerInfo.pDevMode, printerInfo.pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);

                        if (iRet < 0)
                            throw new ApplicationException("Unable to set the orientation setting for this printer.");

                        // GET THE PRINTER INFO SIZE
                        GetPrinter(hPrinter, 9, IntPtr.Zero, 0, out iPrinterInfoSize);
                        if (iPrinterInfoSize == 0)
                            throw new ApplicationException("GetPrinter failed. Couldn't get the # bytes needed for shared PRINTER_INFO_9 structure");

                        // ALLOCATE THE BUFFER
                        hPrinterInfo = Marshal.AllocCoTaskMem(iPrinterInfoSize + 100);

                        // GET A POINTER TO THE PRINTER INFO BUFFER
                        bool bSuccess = GetPrinter(hPrinter, 9, hPrinterInfo, iPrinterInfoSize, out iDummyInt);

                        if (!bSuccess)
                            throw new ApplicationException("GetPrinter failed. Couldn't get the shared PRINTER_INFO_9 structure");

                        // FILL THE PRINTER INFO STRUCTURE
                        printerInfo = (PRINTER_INFO_9)Marshal.PtrToStructure(hPrinterInfo, printerInfo.GetType());
                        printerInfo.pDevMode = hDevMode;

                        // GET A POINTER TO THE PRINTER INFO STRUCTURE
                        Marshal.StructureToPtr(printerInfo, hPrinterInfo, true);

                        // SET THE PRINTER SETTINGS
                        bSuccess = SetPrinter(hPrinter, 9, hPrinterInfo, 0);

                        if (!bSuccess)
                            throw new Win32Exception(Marshal.GetLastWin32Error(), "SetPrinter() failed.  Couldn't set the printer settings");

                        // Tell all open programs that this change occurred.
                        SendMessageTimeout(
                           new IntPtr(HWND_BROADCAST),
                           WM_SETTINGCHANGE,
                           IntPtr.Zero,
                           IntPtr.Zero,
                           CustomPrintForm.SendMessageTimeoutFlags.SMTO_NORMAL,
                           1000,
                           out hDummy);
                    }
                    finally
                    {
                        ClosePrinter(hPrinter);
                    }
                }
                else
                {
                    StringBuilder strBuilder = new StringBuilder();
                    strBuilder.AppendFormat("Failed to open the {0} printer, System error number: {1}",
                        printerName, GetLastError());
                    throw new ApplicationException(strBuilder.ToString());
                }
            }
            else
            {
                structDevMode pDevMode = new structDevMode();
                IntPtr hDC = CreateDC(null, printerName, null, ref pDevMode);
                if (hDC != IntPtr.Zero)
                {
                    const long DM_PAPERSIZE = 0x00000002L;
                    const long DM_PAPERLENGTH = 0x00000004L;
                    const long DM_PAPERWIDTH = 0x00000008L;
                    pDevMode.dmFields = (int)(DM_PAPERSIZE | DM_PAPERWIDTH | DM_PAPERLENGTH);
                    pDevMode.dmPaperSize = 256;
                    pDevMode.dmPaperWidth = (short)(widthMm * 1000.0);
                    pDevMode.dmPaperLength = (short)(heightMm * 1000.0);
                    ResetDC(hDC, ref pDevMode);
                    DeleteDC(hDC);
                }
            }
        }
    }
}


2) I calculated the minimum paper height and width with zero rows (with header, footer, table headings etc.) it is 12 cm width 4.5 cm height (again with zero rows!),

3) Then populated crystal report from data from datagridview through datatable etc

4) Then called below method as
Quote:
callMethod(0, 0);

to create custom paper of (12 cm width) and (4.5cm height + number of rows added by datatable)

height += (rptDocument.Rows.Count * 5F);

multiplied 5f for each row for correcting row height

C#
private void callMethod(float w, float h)
{
    float height = 45f;
    float width = 120f;

    if(w!=0 && h!=0)
    {
        width = w;
        height = h;
    }

    PrintDocument pd = new PrintDocument();
    string defaultPrinter = pd.PrinterSettings.PrinterName;

    height += (rptDocument.Rows.Count * 5F);
    //MessageBox.Show("height= " +height);
    // All MessageBoxes are for debugging purposes (",)
    // this method is called to remove previous "CustomPaper"
    // and add again with changed paper size
    CustomPrintForm.CustomPrintForm.AddCustomPaperSize(defaultPrinter, "CustomPaper", width, height);

    foreach (PaperSize paperSize in pd.PrinterSettings.PaperSizes)
    {
        if (paperSize.PaperName == "CustomPaper")
        {
            //MessageBox.Show("Test: " + rptDocument.PrintOptions.PaperSize);
            try
            {
                rptDocument.PrintOptions.PaperSize = (CrystalDecisions.Shared.PaperSize)paperSize.RawKind;
            }
            catch (Exception Ex)
            {
                MessageBox.Show("Exception: " + Ex);
                return;
            }
            //MessageBox.Show("Test: " + rptDocument.PrintOptions.PaperSize);
            //crystalReportViewer1.Refresh();

        }
    }
    PageMargins pageMargins = new PageMargins
                                  {
                                      leftMargin = 100,
                                      bottomMargin = 0,
                                      topMargin = 0,
                                      rightMargin = 0
                                  };

    rptDocument.PrintOptions.ApplyPageMargins(pageMargins);
    crystalReportViewer1.RefreshReport();
    crystalReportViewer1.Show();

}


Then after this your report will be shown in report viewer with report with whole report on single paper (Custom Size) then just print it on continuous stationary (Paper Roll and not perforated stationary, actually you can print on perforated paper but take caution while tearing...)

!!!Just Most important thing is you must run with elevated privileges as Admin to add/remove/add custom paper to work on Win7, no problem with WinXP!!!

I'm posting in hurry will improve it later in details...
 
Share this answer
 
Some few days back the same issue came in my project also.
The simple and effective solutions is don't use crystal report. try to design text file and print from dos prompt.


print file.txt
type file.txt
copy tile.txt

these command help you to print file from command prompt.

still you want more help from me. plz let me know. sure i will help you.
 
Share this answer
 
Comments
Firdaus Shaikh 28-May-13 13:10pm    
Hello Arun,
Thanks for your reply, I will try this...
try my solution, it works for me!!!

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900