The best VPN 2023

The Best VPS 2023

The Best C# Book

How to realize FastReport.net web direct printing without preview

How to realize FastReport.net web direct printing without preview, I wrote this article because I published the FastReport.net printing function on my Chinese blog site jhrs.com two years ago. This article was cited by many websites. It is also to complete the legacy functions, that is, the web direct printing function, or web silent printing.

Direct printing without preview is also called silent printing, that is, click the button (of course you can start the printer in any way) and the printer directly starts working and printing files; it is easy to implement under WinForm, while web silent printing has always been difficult and more troublesome to implement , This is also the problem to be solved in this article.

I published a series of tens of thousands of articles about FastReport.Net on the Chinese blog site. If you want to read, you can reach it through the link below. Of course, if you don’t understand Chinese, you can use the translation function of chrome.


Source Code Solution

When you download the source code from github, open it with VS2022 and you will see the following style. If JHRS.PrintClientSetup fails to load normally when you open it for the first time, it means that you have not installed Installer Projects. Refer to VS2022 Can’t open vdproj project solution, upgrade Installer Projects This article can be solved.

How to realize FastReport.net web direct printing without preview
FastReport.net web direct printing without preview

Two website programs are provided in the source code, which are written using asp.net webform technology and asp.net core razor page, which are distinguished from the naming; JHRS.PrintClient is a client software packaged based on FastReport.net, reference Dll files related to FastReport.net.

JHRS.PrintClientSetup is a packaged installer, why do I need to package it for installation? That’s because in a production environment you cannot send the files in the Debug or Release directory to customers for their use, and you can’t use them, and you need to use the packaging program to write custom protocol information into the registry, specifically in It will be introduced in the code below. After being packaged into an installation program, the download function can be provided on the webpage in the production environment. Clients that need to use the printing function only need to download and install the client, and then print.

Github: https://github.com/jhrscom/JHRS-PrintClient
Demo : https://fastreport.jhrs.com/

Use FastReport.net to print the demo video directly on the web

How to realize FastReport.net web direct printing without preview

FastReport.net web direct printing without preview

We are using web technology to develop management systems, such as HIS systems in the medical field, corporate ERP systems, financial systems, etc., all have printing requirements, and it is precisely all types of systems and customers that have different printing needs, templates , Formats, data are not the same, etc.; there are many kinds of reports on the market, but we chose FastReport.Net as a third-party component to solve the printing needs. Of course, it is paid for commercial use, but for the company, there is no what is the problem.

The FastReport.Net mentioned in this article uses version 2.0, and it is necessary to purchase an authorization if it is used in the official product. Next, let’s talk about how to use FastReport.net to realize direct printing without preview in the web environment. In addition, I need to explain that you can freely set whether you need to use the preview function in the client I encapsulated. The functions of the client are as follows:

  1. Support to select multiple printers, and can set the default printer
  2. It supports direct printing without previewing, and you can also start the client to turn on the preview function.
  3. Cross browser support, Chrome, IE, FireFox, Edge all support.
  4. Print log function (save in the installation directory)
  5. Desktop shortcut (generally you don’t need to open it, only use it when you change the settings, such as changing the default printer, setting silent printing [no preview])

To realize the silent printing function of FastReport browser, we need to do two steps:

The first step is to write the client program and provide the download function. The user installs the client first when using it for the first time. When you click print for the first time, you will see the following prompt on the browser:

image
How to realize FastReport.net web direct printing without preview

The second step is to provide the printing function and obtain the printing data interface on the web application interface. The specific implementation will be shown in the source code.

Write client-side printing program

The client-side printing program actually encapsulates the FastReport printing component, so we need to write a WinForm form program. Of course, you can also use WPF to implement it. On this form program, you need to drag a PreviewControl control onto the main form. The form program is very simple, just a FastReport.Preview.PreviewControl control. Of course, you can see the others after you clone the source code I put on github, just some auxiliary functions.

How to realize FastReport.net web direct printing without preview
How to realize FastReport.net web direct printing without preview

The complete source code is as follows:

using JHRS.PrintClient.Entity;
using JHRS.PrintClient.Extensions;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Windows.Forms;

namespace JHRS.PrintClient
{
    public partial class MainForm: Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        public string[] args {get; set;}
        /// <summary>
        /// With parameters
        /// </summary>
        /// <param name="args"></param>
        public MainForm(string[] args)
        {
            this.args = args;
            InitializeComponent();
        }

        /// <summary>
        /// Printing method
        /// </summary>
        /// <param name="args"></param>
        private void Print(string[] args)
        {
            var printConfig = ConfigList.FirstOrDefault(x => x.Selected);
            LogHelper.WriteLog($"-------------------------------------------- --Start printing---------------------------------------------- ");
            LogHelper.WriteLog($"Enter the printing method, print setting name: {printConfig?.ConfigName}, printer name: [{printConfig?.DefaultPrinter}], whether to enable the direct printing function: {printConfig?.DirectPrint}");

            if (printConfig == null)
            {
                LogHelper.WriteLog("The default printer is not specified, please make print settings first!");
                LogHelper.WriteLog($"-------------------------------------------- --End printing---------------------------------------------- \r\n\r\n");
                DialogResult result = MessageBox.Show("The default printer is not specified, please make print settings first!", "System prompt", MessageBoxButtons.OK, MessageBoxIcon.Error);
                if (result == DialogResult.OK)
                {
                    DialogResult dialog = new PrintSet().ShowDialog(this);
                    if (dialog == DialogResult.Cancel)
                    {
                        Print(args);
                    }
                }
                return;
            }

            LogHelper.WriteLog($"Print data request interface source: {args[0].Replace("jhrsprint:", "")}");
            HttpClient client = new HttpClient();
            HttpResponseMessage response = client.GetAsync(args[0].Replace("jhrsprint:", "")).Result;
            if (!response.IsSuccessStatusCode)
            {
                return;
            }
            var data = response.Content.ReadAsStringAsync().Result;
            LogHelper.WriteLog($"Print data: {data}");
            PrintData printData = JsonConvert.DeserializeObject<PrintData>(data);

            byte[] arrary = printData.FrxFile.Split('^').Select(x => (byte)int.Parse(x)).ToArray();

            report1.Preview = previewControl1;

            report1.Load(new MemoryStream(arrary));
            report1.RegisterData(printData.Data, "Print Data Source");
            
            report1.PrintSettings.Printer = printConfig.DefaultPrinter;
            LogHelper.WriteLog($"-------------------------------------------- --End printing---------------------------------------------- \r\n\r\n");
            if (printConfig.DirectPrint)
            {
                report1.PrintSettings.ShowDialog = false;
                report1.Print();
                ExitSystem();
            }
            else
            {
                report1.Prepare();
                report1.ShowPrepared();
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            if (args != null)
            {
                Print(args);
            }
            SetMenuItem();
        }

        /// <summary>
        /// Set the default printer
        /// </summary>
        public void SetMenuItem(bool reload = false)
        {
            reloadConfig = reload;
            var arrary = ConfigList.Select(x => x.ConfigName).ToArray();
            if (arrary.Length == 0)
            {
                toolStripComboBox1.Items.Add("not set");
                toolStripComboBox1.SelectedIndex = 0;
            }
            else
            {
                toolStripComboBox1.Items.Clear();
                toolStripComboBox1.Items.AddRange(ConfigList.Select(x => x.ConfigName).ToArray());
                var selected = ConfigList.FirstOrDefault(x => x.Selected);
                if (selected != null) toolStripComboBox1.SelectedItem = selected.ConfigName;
            }
        }

        private bool reloadConfig = false;
        private List<Configs> list;
        private List<Configs> ConfigList
        {
            get
            {
                if (list == null || reloadConfig == true)
                {
                    list = XmlHelper.Deserialize<List<Configs>>(Constants.ConfigSavePath);
                    reloadConfig = false;
                }
                if (list != null) return list;
                return list ?? new List<Configs>();
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            MessageBoxButtons mess = MessageBoxButtons.OKCancel;
            var printConfig = ConfigList.FirstOrDefault(x => x.Selected);
            if (printConfig != null && printConfig.DirectPrint)
            {
                ExitSystem();
            }
            else
            {
                DialogResult dr = MessageBox.Show("Are you sure you want to exit the print client?", "System prompt", mess, MessageBoxIcon.Question);
                if (dr == DialogResult.OK)
                    ExitSystem();
                else
                    e.Cancel = true;
            }
        }

        private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (this.WindowState == FormWindowState.Minimized)
                {
                    this.WindowState = FormWindowState.Maximized;
                    this.ShowInTaskbar = true;
                }
                this.Activate();
            }
        }

        private void Exit the print client ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBoxButtons mess = MessageBoxButtons.OKCancel;
            DialogResult dr = MessageBox.Show("Are you sure you want to exit the print client?", "System prompt", mess, MessageBoxIcon.Question);
            if (dr == DialogResult.OK) ExitSystem();
        }

        private void print settings ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var set = new PrintSet();
            if (set.ParentForm == null)
            {
                set.StartPosition = FormStartPosition.CenterScreen;
            }
            set.ShowDialog(this);
        }

        /// <summary>
        /// Change print settings
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripComboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            var list = ConfigList;
            foreach (var item in list)
            {
                if (item.ConfigName == toolStripComboBox1.SelectedItem.ToString())
                {
                    item.Selected = true;
                }
                else
                {
                    item.Selected = false;
                }
            }

            XmlHelper.SerializeToXmlFile(list);
        }

        private void print log ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new LogForm().ShowDialog(this);
        }

        /// <summary>
        /// Exit system
        /// </summary>
        private void ExitSystem()
        {
            notifyIcon.Dispose();
            Environment.Exit(0);
        }
    }

    /// <summary>
    /// Print data entity
    /// </summary>
    public class PrintData
    {
        /// <summary>
        /// The report used by the data to be printed will be returned by the server to tell the client control
        /// </summary>
        public string FrxFile {get; set;}

        /// <summary>
        /// Report data source, returned by the server
        /// </summary>
        public DataTable Data {get; set;}
    }
}

How to realize FastReport.net web direct printing without preview

In the Print(string[] args) method in the above code, the args parameter is passed in through a custom protocol. This method is the final call to the FastReport.Net component to achieve the printing function on the (client) browser, which is fully equipped Same function as desktop software. For the content of the custom protocol, see the following article:

Customize the protocol to open the local client program

Write the installer class

The purpose of the installer class is to write the custom protocol information into the registry. When you install the client program, it will be automatically called by the installer of the operating system. Of course, you need to make some settings in the packaging project. The source code of the complete installer class is as follows:

using Microsoft.Win32;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Threading.Tasks;

namespace JHRS.PrintClient
{
    [RunInstaller(true)]
    public partial class PrintInstall: Installer
    {
        public PrintInstall()
        {
            InitializeComponent();
        }

        protected override void OnAfterInstall(IDictionary savedState)
        {
            string path = this.Context.Parameters["targetdir"];
            //Get the installation target path set by the user, note that you need to add /targetdir="[TARGETDIR]\" in the CustomActionData in the property bar of the custom operation in the Setup project
            LogWrite(path);

            const string UriScheme = "jhrsprint";
            const string FriendlyName = "jhrsprint custom protocol";
            using (var key = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Classes\\" + UriScheme))
            {
                string applicationLocation = path.Substring(0, path.Length-1) + @"JHRS.PrintClient.exe";
                LogWrite($"Print client installation path: {applicationLocation}");
                key.SetValue("", "URL:" + FriendlyName);
                LogWrite($"Custom Protocol Name: URL:{FriendlyName}");
                key.SetValue("URL Protocol", "");

                using (var defaultIcon = key.CreateSubKey("DefaultIcon"))
                {
                    defaultIcon.SetValue("", applicationLocation + ",1");
                }

                using (var commandKey = key.CreateSubKey(@"shell\open\command"))
                {
                    commandKey.SetValue("", "\"" + applicationLocation + "\" \"%1\"");
                }
                LogWrite($"The setting is over! The key.Name is: {key.Name},{key}");
            }
            base.OnAfterInstall(savedState);
        }
        public override void Install(IDictionary stateSaver)
        {
            LogWrite("Install!");
            base.Install(stateSaver);
        }

        protected override void OnBeforeInstall(IDictionary savedState)
        {
            LogWrite("OnBeforeInstall!");
            base.OnBeforeInstall(savedState);
        }
        public override void Uninstall(IDictionary savedState)
        {
            LogWrite("Uninstall!"); base.Uninstall(savedState);
        }
        public override void Rollback(IDictionary savedState)
        {
            LogWrite("Rollback");
            base.Rollback(savedState);
        }

        public void LogWrite(string str)
        {
#if DEBUG
            string LogPath = @"c:\log\";
            if (!System.IO.Directory.Exists(LogPath)) System.IO.Directory.CreateDirectory(LogPath);
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(LogPath + @"SetUpLog.txt", true))
            {
                sw.WriteLine(DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss] ") + str + "\n");
            }
#endif
        }
    }
}

How to realize FastReport.net web direct printing without preview

After the web printing client is installed, a shortcut will be generated on the desktop, and it is usually not used unless you need to do some settings on the client.

How to realize FastReport.net web direct printing without preview
How to realize FastReport.net web direct printing without preview

Finished the preparation of the web client program and the setting of the packaging program, the rest of the operation you only need to package the client, and then put it in the website directory, and provide a download function for users to download and install your client. .

Next, let’s take a look at how the FastReport web printing function is used on the website.

FastReport web print page code

To trigger the printing function on the page, it is usually achieved by placing buttons or links. As the following code, I use asp.net core razor page to write. A button is placed on the page, and then the request is submitted to the current page for processing.

<input type="button" value="Download and install the client" onclick="location.href='?handler=Download'" />

The complete code can be found on github. The sample code for spooling print requests, that is, obtaining print data is as follows:

        /// <summary>
        /// Get print data
        /// </summary>
        /// <returns></returns>
        public ContentResult OnGetPrintData()
        {
            if ("https://jhrs.com".Equals(Request.Query["par1"].ToString())&& "znlive.com".Equals(Request.Query["myblog"].ToString()))
            {
                List<SbEntity> list = new List<SbEntity>();
                for (int i = 0; i <1; i++)
                {
                    list.Add(new SbEntity
                    {
                        Title = "Signs of Ultrasound Equipment in Jianghu People's Hospital",
                        Use department = "Ultrasound department-" + i,
                        Enable date = DateTime.Now.AddDays(i),
                        Model = "XH34534-" + i,
                        Serial number = "XLH-3452" + i,
                        Serial number = (i + 1).ToString(),
                        Barcode = "BH20190302002" + i,
                        QR code = "https://znlive.com/the-best-cheap-vpn",
                        Manufacturer = "jhrs.com Technology Co., Ltd.",
                        Specification = "GGX-1" + i,
                        Device name = "X-ray transmitter",
                        Responsible person = "Zhao Jiafa",
                        Warranty date = DateTime.Now.AddYears(i + 1)
                    });
                }

                var print = new PrintDataEntity<List<SbEntity>> {Data = list };
                var path = Path.Combine(Environment.CurrentDirectory, "wwwroot/print/equipment sign.frx");
                using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
                {
                    try
                    {
                        byte[] buffur = new byte[fs.Length];
                        fs.Read(buffur, 0, (int)fs.Length);
                        print.FrxFile = string.Join("^", buffur);
                    }
                    catch (Exception ex)
                    {
                        return Content(new {Success = false, ErrorMsg = ex.Message }.ToJson());
                    }
                }
                return Content(print.ToJson());
            }
            return Content(new {Success = false, ErrorMsg = "The parameter is wrong" }.ToJson());
        }

How to realize FastReport.net web direct printing without preview

How about it, isn’t it simple? In the demo website, the download function is also provided, so I won’t introduce too much here. You can find the complete solution source code on github.

Last reminder: The FastReport.net component is a paid product. You need to purchase an authorization during the use process. You can contact the online support on their official website to purchase. The 2.0 learning version provided below is relatively old, and the interface style of the latest version has also changed, but the way to use it is similar.

Summarize
This article is relatively simple. If you are a novice, and don’t know much about FastReport.net, or are not familiar with FastReport.net, you will encounter a lot of problems. I wanted to draw a picture to illustrate, but think about it. Forget it, after all, when the people who read this article are developers and have needs, they should understand it.

By the way, this article does not explain how to use FastReport.net, such as how to make report files, how to bind data sources, how to add dictionary files, etc. You only need to look at the demo program provided by FastReport.net to understand these contents. For learning and use, here is a web disk download address, you can download FastReport.net to learn.

You need to be prepared when downloading. This TMD network disk needs to be clicked several times to download the advertisement. . Of course money can solve all problems.

FastReport.net 2.0 download link: click to download

How to realize FastReport.net web direct printing without preview
How to realize FastReport.net web direct printing without preview

Leave a Comment