How to print the entire string if the length exceeds the page

Asked

Viewed 709 times

4

I have to print one string which may vary in size. What I need is that if this string does not fit on the page the remaining text is printed on another. I know that for this I need to do something using e.HasMorePages but I don’t know how. I did some research but I didn’t find anything relevant. Take a look at part of the code that appears in the event printPage:

string textoFinal = "\n\n\n\n\n\n\n\n\n\n\n" + cabInf + cab + sb.ToString() + soma + stringObs + final + final2;

StringFormat alinhar = new StringFormat(StringFormatFlags.NoClip);

alinhar.Alignment = StringAlignment.Near;

e.Graphics.DrawString(textoFinal, Fonte, Brushes.Black, e.MarginBounds, alinhar);

e.HasMorePages = false;

If I die to true the e.HasMorePages when printing I get a page count loop. I need something to check if the string has exceeded the page limit and, if exceeded, the text that did not fit should be printed on another page.

EDIT
I have this code to print out:

string textoFinal;
string stringCopia;

internal void Imprimir()
{
    Cliente cliente = Clientes[listaClientes.SelectedIndex];

    StringBuilder sb = new StringBuilder();
    foreach (var cli in cliente.Produtos)
    {
        sb.AppendFormat("\n\n{0}.....................Valor: R${1} - Data: {2}", cli.NomeProduto, cli.ValorProduto, cli.DataCompra);
    }
    textoFinal = sb.ToString();
    stringCopia = textoFinal;
    printDocumento.PrintPage += printDocumento_PrintPage;
    Margins margem = new Margins(20, 20, 20, 20);
    printDocumento.DefaultPageSettings.Margins = margem;
    printPrevisao.ShowDialog();
}

At the event printPage appears:

int caracteresNaPagina = 0;
int linhasPorPagina = 0;

var Fonte = new Font("Arial", 9);

e.Graphics.DrawImage(Properties.Resources.logoI, 20, 20);

StringFormat alinhar = new StringFormat(StringFormatFlags.NoClip);

alinhar.Alignment = StringAlignment.Near;

e.Graphics.MeasureString(stringCopia, Fonte, e.MarginBounds.Size, alinhar, out caracteresNaPagina, out linhasPorPagina);

e.Graphics.DrawString(stringCopia, Fonte, Brushes.Black, e.MarginBounds, alinhar);

stringCopia = stringCopia.Substring(caracteresNaPagina);

e.HasMorePages = stringCopia.Length > 0;

if (!e.HasMorePages)
    stringCopia = textoFinal;

This way the rest of the text that did not fit on the page is being written at the beginning of the same page, shuffling the texts instead of moving to another page.

PROBLEM SOLVING
Worked perfectly after removing the line printDocumento.PrintPage += printDocumento_PrintPage;
Why? Because I’m developing this in winforms and already had this method pointing to the event. In this way, the text was written twice on the printing document and scrambled.

1 answer

3


What you need to do and measure the text you print:

int caracteresNaPagina = 0;
int linhasPorPagina = 0;

e.Graphics.MeasureString(textoFinal, font,
    e.MarginBounds.Size, StringFormat.GenericTypographic,
    out charactersOnPage, out linesPerPage);

Then print the text and remove from the original text the characters that have already been printed. If there are still characters, set the property HasMorePages to true.

e.Graphics.DrawString(textoFinal, font, Brushes.Black,
    e.MarginBounds, StringFormat.GenericTypographic);

textoFinal= textoFinal.Substring(caracteresNaPagina);

e.HasMorePages = (textoFinal.Length > 0);

In this way the event will continue to be called until no characters exist to print, i.e, when HasMorePages is placed the false.

Note that the text to be printed has to be created in advance (outside the print event).

EDIT:

The control PrintPreviewDialog you’re using to make the preview of the document to be printed calls twice the event PrintPage. The first time he created the preview and the second time if the print button is pressed (and printing is effective).

Due to this and assuming that the text was created outside the event PrintPage, due to the logic to calculate the extra pages, the text will be removed until there are no characters left to print.

textoFinal= textoFinal.Substring(caracteresNaPagina);

e.HasMorePages = (textoFinal.Length > 0);

The problem with this is that the second time you print, when you reuse textoFinal, there are no more characters to print, hence the effective print appears blank. The solution to this will then be.

  • Create text to print
  • Create a copy of the text to print
  • Use the copy created within the event PrintPage

That is to say:

string textoFinal = [crie aqui o seu texto];
string copiaTextoFinal = textoFinal; // Copia do texto. Vao ser removidos caracteres a medida que a impressao ocorre.
PrintPreviewDialog dialog = new PrintPreviewDialog
    {
        Document = new PrintDocument()
    };

dialog.Document.PrintPage += (sender, e) =>
    {
        int charactersOnPage;
        int linesPerPage;

        var fonte = new Font("Arial", 18);

        e.Graphics.MeasureString(copiaTextoFinal, fonte,
                e.MarginBounds.Size, StringFormat.GenericTypographic,
                out charactersOnPage, out linesPerPage);

        e.Graphics.DrawString(copiaTextoFinal, fonte, Brushes.Black, e.MarginBounds, StringFormat.GenericTypographic);

        copiaTextoFinal = copiaTextoFinal.Substring(charactersOnPage);

        // Verifica se ainda existem caracteres para imprimir. Se não, marca a 
        // propriedade como falsa.
        e.HasMorePages = copiaTextoFinal.Length > 0;

        // Se não houverem mais paginas a imprimir, volta a copiar o texto original
        // para a variável de copia. Assim, da próxima vez que o evento for chamado, 
        // tem o texto completo, pronto a imprimir.
        if (!e.HasMorePages)
            copiaTextoFinal = textoFinal;
    };

dialog.ShowDialog();
  • This was the first method I used, I saw there in MSDN. I was trying to put the text to be printed inside the event printPage. I tried putting the text in the code that calls the event. The text appears to me in the preview but the sheet comes out blank when printed. In the print preview the text that does not fit at the end of the sheet is getting shuffled at the beginning of the sheet.

  • In my function to print it printDocumento.PrintPage += printDocumento_PrintPage;
Margins margem = new Margins(20, 20, 20, 20);
printDocumento.DefaultPageSettings.Margins = margem;
printPrevisao.ShowDialog();

  • I don’t have a reputation high enough to use chat.

  • The printPrevisao.ShowDialog(); is within the function OnClick one-button.

  • I am examining and seeing how I can implement here! The text in the case cannot be created within the event along with the copy?

  • No, otherwise it will create the text every time the event runs, so it has no way of knowing which text is already printed.

  • Your code worked in parts. Now the sheet is printed but the rest of the string that did not fit on the page is shuffled at the beginning of the sheet instead of printing on another sheet.

  • Even if I replace it with mine StringFormat alinhar the text remains embarrassed at the beginning of the page. What may be going wrong?

  • I have been testing your code. Your problem is the logo? With your code, the logo is on top of the first printing lines.

  • I use \n\n\n\n\n\n\n\n\n\n\n to scroll down the text on the page. The problem in this case is the pages themselves. Instead of the remaining text moving to another page, it goes back there at the beginning and mixes with the image and the text. I only have one page in the preview. I would need to have two: one with the image and the text and the other with the text that did not fit.

  • To begin with, you should solve this error. The text should not be lowered with \n but adjusting the way the image is to be drawn on the page (manipulating the x and y coordinates)

  • Even removing the line that draws the image the texts remain embarrassed there at the beginning. I think there is something wrong in the page count.

  • Omni, in your tests you were successful passing part of the text that did not fit to another page without the same return to the beginning and embarrass?

  • Worked perfectly after removing the line printDocumento.PrintPage += printDocumento_PrintPage;. Thank you so much for your help!

Show 9 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.