How to print bitmap without zoom from MVC controll

2019-06-14 15:18发布

Document is printed from MVC controller to Debian Squeeze Linux server printer using code below in Mono.

Page in printer is A4.

Printed text in paper is too big and unsharp. Rightmost part of text is not visible since it does not fit to page.

If printed from Windows from .NET to HP Laserjet, output is correct.

So it looks like Mono or Samsung ML-331x Series printer zooms bitmap for unknown reason which causes too big and unsharp output.

How to fix this so that bitmap is printed like in windows ?

Possible solutions:

  1. Best way would be to print formatted html directly. How to do it in server where there are no browser installed? wkhtmltopdf does not support printing. I posted it in How to print formatted html in Linux server

  2. Maybe it is possible to use wkhtmltopdf convert html to pdf instead of bitmap I posted it as separate question in How to print pdf in debian linux from MVC controller

  3. wkhtmltoimage can produce also other image formats. Maybe some other format is better ?

  4. Maybe some wkhtmltoimage command line swithches like --width=750 or --dpi can fix this ?

public class Test: Controller
{
    public ActionResult Print()
    {
        PrintOrderVormiga();
        return new ContentResult() { Content = "OK" };
    }

    void PrintOrderVormiga()
    {
        StringBuilder sb = new StringBuilder();
        sb.Insert(0, " test ", 500);
        var bmp = ConvertHtmlToBMP("<html><body>" +sb.Tostring()+ "</body></html>");
        var doc = new PrintDocument();
        doc.PrinterSettings.PrinterName = "Samsung ML-331x Series";
        doc.PrintPage += new PrintPageEventHandler(ProvideContent);
        pageHeight = doc.DefaultPageSettings.PaperSize.Height;
        using (bm = new Bitmap(new MemoryStream(bmp)))
        {
            lehti = (int)Math.Ceiling(bm.Height / (double)pageHeight);
            doc.PrinterSettings.FromPage = 1;
            doc.PrinterSettings.ToPage = lehti;
            pageno = 0;
            doc.Print();
        }
    }

    int pageno, lehti;
    int pageHeight;
    Bitmap bm;

    void ProvideContent(object sender, PrintPageEventArgs e)
    {
        Rectangle cropRect = new Rectangle(0, pageHeight * pageno++,
            bm.Width, pageHeight);
        Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);
        e.Graphics.DrawImage(bm, new Rectangle(0, 0, target.Width, target.Height),
                       cropRect,
                       GraphicsUnit.Pixel);
        e.HasMorePages = pageno < lehti;
    }

    static byte[] ConvertHtmlToBMP(string html)
    {
        string programm = "wkhtmltoimage";
        if (Environment.OSVersion.Platform != PlatformID.Win32NT)
        {
            programm = "wkhtmltoimage-amd64";
        }

        var p = new Process
        {
            StartInfo =
            {
                CreateNoWindow = true,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                RedirectStandardInput = true,
                UseShellExecute = false,
                FileName = Environment.OSVersion.Platform == PlatformID.Win32NT ?
                "C:\\Program Files\\wkhtmltopdf\\bin\\" + programm + ".exe" : "/usr/bin/" + programm
            }
        };

        p.StartInfo.Arguments = "--format bmp --disable-javascript --quality 10";
        p.StartInfo.Arguments += " - -";
        p.Start();
        using (var stream = p.StandardInput)
        {
            byte[] ibuffer = System.Text.Encoding.UTF8.GetBytes(html);
            stream.BaseStream.Write(ibuffer, 0, ibuffer.Length);
            stream.WriteLine();
        }

        var buffer = new byte[32768];
        byte[] file;

        using (var ms = new MemoryStream())
        {
            while (true)
            {
                var read = p.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);
                if (read <= 0)
                {
                    break;
                }
                ms.Write(buffer, 0, read);
            }
            file = ms.ToArray();
        }

        p.WaitForExit(60000);
        var returnCode = p.ExitCode;
        p.Close();
        return file;
    }
}

1条回答
冷血范
2楼-- · 2019-06-14 16:07

You can use this HTML to PDF Converter for Mono solution from EvoPdf. The C# code for converting a HTML to PDF in Mono is:

        // create the HTML to PDF converter object
        HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter(serverIPAddress, serverPortNumber);

        // set service password if necessary
        if (serverPassword.Length > 0)
            htmlToPdfConverter.ServicePassword = serverPassword;

        // set PDF page size
        htmlToPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;

        // set PDF page orientation
        htmlToPdfConverter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Portrait;

        // convert the HTML page from given URL to PDF in a buffer
        byte[] pdfBytes = htmlToPdfConverter.ConvertUrl(urlToConvert);
查看更多
登录 后发表回答