Home > database >  How to print several images per page
How to print several images per page

Time:10-05

I have generated several images at the runtime and I need to print them. Those are barcodes so the height can be fixed but the number is not know beforehand so more pages might be necessary. Let's say for example that a maximum of 4 images can fit in each A4 page. Below the image a textbox with the content of the barcode might help but it's not necessary.

enter image description here

For printing I use

PrintDialog printDialog = new PrintDialog();
bool? pdResult = printDialog.ShowDialog();
if (pdResult != null && pdResult.Value)
{
    FixedDocument document = CreateFixedDocument();
    printDialog.PrintDocument(document.DocumentPaginator, "ID Card Printing");
}

and that was easy. But before I need to create the page so

private FixedDocument CreateFixedDocument()
{
    FixedDocument fixedDocument = new FixedDocument();
    fixedDocument.DocumentPaginator.PageSize = new Size(???); <---have not understood how to set A4 here

        //for (int i = 0; i < (numBarcodes/4); i  )
        {
            PageContent page = new PageContent();
            FixedPage fixedPage = CreateOneFixedPage();
            ((IAddChild)page).AddChild(fixedPage);
            fixedDocument.Pages.Add(page);
        }
        return fixedDocument;
    }

and then even more complicated I create one page

private FixedPage CreateOneFixedPage()
{
    FixedPage page = new FixedPage();
    page.Width = ???
    page.Height = ???

    TextBlock tbTitle = new TextBlock();
    tbTitle.Text = <----------the barcode content
    tbTitle.FontSize = 24;
    tbTitle.Foreground = new SolidColorBrush(Colors.White);
    tbTitle.FontFamily = new FontFamily("Arial");
    FixedPage.SetLeft(tbTitle, ????)
    FixedPage.SetTop(tbTitle, ?????)
    page.Children.Add((UIElement)tbTitle);

    Image image = new Image
    {

        Height = 30,
        Width = 30
    };
    image.Source = imgbarcode.Source;

    
    FixedPage.SetLeft(b, ???);
    FixedPage.SetTop(b, ???); // top margin
    page.Children.Add((UIElement)b);

    //measure size of the layout
    Size sz = new Size(???);
    page.Measure(sz);
    page.Arrange(new Rect(new Point(), sz));
    page.UpdateLayout();

    return page;
}

Any help is appreciated for I have already printed way too many pages! Thanks

CodePudding user response:

You can use that:

const double dPageWidth_Cm = 21.7;
const double dPageHeight_Cm = 29;
const double dBarcodeImgWidth_Px = 800;
const double dBarcodeImgHeight_Px = dBarcodeImgWidth_Px/4;
const double dVerticalSpacing_Cm = 5;
const double dVerticalSpacingInitial_Cm = dVerticalSpacing_Cm/ 2;


private FixedPage CreateOneFixedPage()
{
    #region 0 Page
    FixedPage page = new FixedPage();
    page.Width = 96 * dPageWidth_Cm;
    page.Height = 96 * dPageHeight_Cm;
    #endregion

    #region 1 Header
    var tbkTitle = new TextBlock();
    tbkTitle.Text = "Title for Barcodes";
    tbkTitle.HorizontalAlignment = HorizontalAlignment.Center;
    tbkTitle.TextAlignment = TextAlignment.Center;
    tbkTitle.FontSize = 80;
    FixedPage.SetLeft(tbkTitle, 96 * (dPageWidth_Cm / 2) - (MeasureTextBlock(tbkTitle).Width / 2));
    page.Children.Add((UIElement)tbkTitle);
    #endregion

    #region 2 Barcodes
    for (int iii = 0; iii < numBarcodes; iii  )
    {
        var img = new Image { Source = imgbarcode.Source };
        FixedPage.SetLeft(img, 96 * dPageWidth_Cm / 2 - dBarcodeImgWidth_Px / 2);//from the center of the page half the img size
        FixedPage.SetTop(img, 96 * (dVerticalSpacing_Cm * iii   dVerticalSpacingInitial_Cm));
        page.Children.Add((UIElement)img);

        var tbkBarcode = new TextBlock();
        tbkBarcode.Text = txtbarcodecontent.Text   "  "   iii;
        tbkBarcode.FontSize = 40;
        FixedPage.SetLeft(tbkBarcode, 96 * dPageWidth_Cm / 2 - (MeasureTextBlock(tbkBarcode).Width / 2));
        FixedPage.SetTop(tbkBarcode, 96 * (dVerticalSpacing_Cm * iii   dVerticalSpacing_Cm / 2)   dBarcodeImgHeight_Px);
        page.Children.Add((UIElement)tbkBarcode);
    }
    #endregion


    #region 3 Footer
    var tbkFooter = new TextBlock();
    tbkFooter.Text = "Footer for Barcodes";
    tbkFooter.HorizontalAlignment = HorizontalAlignment.Center;
    tbkFooter.TextAlignment = TextAlignment.Center;
    tbkFooter.FontSize = 40;
    FixedPage.SetLeft(tbkFooter, 96 * (dPageWidth_Cm / 2) - (MeasureTextBlock(tbkFooter).Width / 2));
    FixedPage.SetBottom(tbkFooter, 0);
    page.Children.Add(tbkFooter);
    #endregion

    return page;
}

private Size MeasureTextBlock(TextBlock tbk)
{
    var formattedText = new FormattedText(tbk.Text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
        new Typeface(tbk.FontFamily, tbk.FontStyle, tbk.FontWeight, tbk.FontStretch),tbk.FontSize,
        Brushes.Black, new NumberSubstitution(), 1);
    return new Size(formattedText.Width, formattedText.Height);
}

I had to use the MeasureTextBlock function for I couldn't get the normal stackPanel center logic work. And the result is therefore the following:

enter image description here

If you need more pages just repeat the logic and create more pages

  • Related