在winforms中如何使用自定义纸张大小进行打印?

23

我正在尝试在我的应用程序中打印一个文档。但是在不同的打印机上,我得到了不同的结果。这是我的代码:

PaperSize paperSize = new PaperSize("My Envelope", 440, 630);
paperSize.RawKind = (int)PaperKind.Custom;

PrintDocument pd = new PrintDocument();
pd.PrintPage += (sender, args) => Console.Out.WriteLine("Printable Area for printer {0} = {1}", args.PageSettings.PrinterSettings.PrinterName, args.PageSettings.PrintableArea);

pd.DefaultPageSettings.PaperSize = paperSize;
pd.DefaultPageSettings.Landscape = true;
pd.DefaultPageSettings.Margins   = new Margins(60, 40, 20, 20);

Console.Out.WriteLine("My paper size: " + pd.DefaultPageSettings.PaperSize);

PrintDialog printDialog = new PrintDialog(); // to choose printer
printDialog.Document = pd;

if (printDialog.ShowDialog(this) == DialogResult.OK)
{
    // pd.DefaultPageSettings.PaperSize = paperSize; // uncomment to override size from dialog

    Console.Out.WriteLine("Paper size for printer {0} = {1}", printDialog.PrinterSettings.PrinterName, pd.DefaultPageSettings.PaperSize);
    _sptTxtControl.Print(pd);
}

当弹出对话框时,我有两台打印机 - 三星和惠普。这是这两台打印机的控制台输出:

My paper size: [PaperSize My Envelope Kind=Custom Height=630 Width=440]
Paper size for printer HP LaserJet 1022n = [PaperSize A4 Kind=A4 Height=1169 Width=827]
Printable Area for printer HP LaserJet 1022n = {X=21,83333,Y=15,66667,Width=789,3333,Height=1137,333}

My paper size: [PaperSize My Envelope Kind=Custom Height=630 Width=440]
Paper size for printer Samsung SCX-4x28 Series PCL6 = [PaperSize A4 Kind=A4 Height=1169 Width=827]
Printable Area for printer Samsung SCX-4x28 Series PCL6 = {X=17,33333,Y=17,16667,Width=792,3333,Height=1135,167}
你可以看到对话框正在更改大小为A4。如果你取消 showdialog 后的注释,我将强制使用纸张大小。打印时的输出结果如下所示:

您可以看到对话框正在更改大小为A4。因此,如果取消 showdialog 后的注释,我将强制使用纸张大小。打印输出如下:

My paper size: [PaperSize My Envelope Kind=Custom Height=630 Width=440]
Paper size for printer HP LaserJet 1022n = [PaperSize My Envelope Kind=Custom Height=630 Width=440]
Printable Area for printer HP LaserJet 1022n = {X=21,83333,Y=15,66667,Width=789,3333,Height=1137,333}

My paper size: [PaperSize My Envelope Kind=Custom Height=630 Width=440]
Paper size for printer Samsung SCX-4x28 Series PCL6 = [PaperSize My Envelope Kind=Custom Height=630 Width=440]
Printable Area for printer Samsung SCX-4x28 Series PCL6 = {X=16,66667,Y=20,Width=400,1667,Height=589,8333}
你可以看到,三星打印机有很好的可打印区域,而惠普则没有。无论我在代码中如何更改(设置原始边距等),惠普始终是A4大小。
如果我在打印属性中更改纸张设置(抱歉,这里是波兰语对话框): custom paper settings 并在显示对话框后不更改纸张大小,则惠普打印一切都正常。输出结果如下:
My paper size: [PaperSize My Envelope Kind=Custom Height=630 Width=440]
Paper size for printer HP LaserJet 1022n = [PaperSize My Envelop Format Kind=Custom Height=630 Width=440]
Printable Area for printer HP LaserJet 1022n = {X=18,66667,Y=16,Width=405,3333,Height=597,3333}

但是我不想强制用户保存打印机的自定义尺寸。我也尝试了使用Kyocera打印机 - 这可以工作,但对于其他两台惠普打印机则不行。

最糟糕的部分是Word 2010在这两台打印机上使用相同大小的RTF文档进行打印没有问题,所以我不能怪惠普驱动程序。

有什么想法吗?


31
不,我换工作了 ;) - bizon
糟糕!希望我也不必这样做!! - alfoks
1
@bizon 哈哈哈哈,你这个笑话真是让我开心... :D - Core
2个回答

16
在 PrintDialog 关闭后,不要只设置
pd.DefaultPageSettings.PaperSize = paperSize;

也尝试着设置一下

pd.PrinterSettings.DefaultPageSettings.PaperSize = paperSize;

我认为那会照顾好它的。


4
设置
pd.DefaultPageSettings.PaperSize = paperSize;

并且

pd.PrinterSettings.DefaultPageSettings.PaperSize = paperSize;

有时可能无法正常工作。

最合适的做法是选择已安装在打印机驱动程序或计算机中的自定义纸张大小,然后设置以下属性

pd.DefaultPageSettings.PaperSize = ExistingPaperSize;
pd.PrinterSettings.PaperSize = ExistingPaperSize;

像这段代码一样

    PrintDocument pd = new PrintDocument();
    pd.PrinterSettings = printdg.PrinterSettings;
    PaperSize RequiredPaperSize = CalculatePaperSize(WIDTH,HEIGHT);
    bool FoundMatchingPaperSize = false;
    for (int index = 0; index < pd.PrinterSettings.PaperSizes.Count; index++)
    {
         if (pd.PrinterSettings.PaperSizes[index].Height == RequiredPaperSize.Height && pd.PrinterSettings.PaperSizes[index].Width == RequiredPaperSize.Width)
          {
              pd.PrinterSettings.DefaultPageSettings.PaperSize = pd.PrinterSettings.PaperSizes[index];
              pd.DefaultPageSettings.PaperSize = pd.PrinterSettings.PaperSizes[index];
              FoundMatchingPaperSize = true;
              break;
           }
    }


    //Method to calculate PaperSize from Centimeter to 1/100 of an inch
 /// Caclulates the paper size
    /// </summary>
    /// <param name="WidthInCentimeters"></param>
    /// <param name="HeightInCentimetres"></param>
    /// <returns></returns>
    public static System.Drawing.Printing.PaperSize CalculatePaperSize(double WidthInCentimeters, 
        double HeightInCentimetres)
    {
        int Width = int.Parse( ( Math.Round ((WidthInCentimeters*0.393701) * 100, 0, MidpointRounding.AwayFromZero) ).ToString() );
        int Height = int.Parse( ( Math.Round ((HeightInCentimetres*0.393701) * 100, 0, MidpointRounding.AwayFromZero) ).ToString() );

        PaperSize NewSize = new PaperSize();
        NewSize.RawKind = (int)PaperKind.Custom;
        NewSize.Width = Width;
        NewSize.Height = Height;
        NewSize.PaperName = "Letter";

        return NewSize;

    }

FYI,这一行是错误的:pd.PrinterSettings.PaperSize = ExistingPaperSize; 因为没有 pd.PrinterSettings.PaperSize 属性。应该改为 pd.PrinterSettings.DefaultPageSettings.PaperSize - Endy Tjahjono
最新的Windows 10更新似乎破坏了向打印管理器添加自定义表单的功能。我之前添加的一个表单在更新后消失了,即使重新添加,新表单仍不显示在“PaperSizes”集合中。然而我不知道可以动态创建所需的表单,这解决了我的问题,省去了创建自定义表单的麻烦。谢谢! - Steve In CO

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