javascriptcssblazorblazor-server-side

How to include CSS in JS script when printing HTML?


I'm trying to create a Blazor Server application with JS script which will print from HTML.

I'm trying to programatically include an image within it so having HTML and then executing printWindow.document.write("<img src="${imageBinaryHere}">"); would make it simpler for me.

The code that I have for now is following:

window.printCard = function (imageBinaryHere) {
    var printWindow = window.open('', '_blank');
    printWindow.document.open();
    printWindow.document.write('<!DOCTYPE html><html> A bunch of HTML going here including <link href="{serverUrl}/css/printStyles.css" rel="stylesheet" /></html>')

    printWindow.document.write(`<img src="${imageBinaryHere}">`);

    printWindow.document.close();
    printWindow.print();
    printWindow.close();
}

I have 2 issues that are occurring for me:

  1. Is that printStyles.css is not included in the print window, therefore just rendering HTML without any styling. I'm not sure if I'm including it properly or what's the problem here?
  2. Even if I add inline css for example <body style="background-color:red;"> it doesn't change it on the print preview document, but rather on the whole page like this: enter image description here

Any ideas on what I'm doing wrong, this is the first time I'm trying to implement printing. Keep in mind this is Blazor server executing this script like this:

protected async Task Print()
{
   await JsRuntime.InvokeVoidAsync("printCard", imageBinary);
}

Solution

  • I have solved this by doing the following:

    1. Add the HTML that you need to print into HtmlToPrint.razor file. Have a div and then within it body tag and then the rest of your HTML.

    2. Then add the HtmlToPrint.razor .css file which will act as a scoped CSS for that HtmlToPrint.razor file.

    3. When adding CSS wrap it in @media print {} so that it is scoped to printing only.

    4. In the CSS file in .body {} class add -webkit-print-color-adjust: exact;

    5. Into HtmlToPrint.razor .cs file add a function to call printing

      protected async Task Print()
      {
          await JsRuntime.InvokeVoidAsync("{nameOfTheJSFunctionYouAreCalling}");
      }
      
    6. Within wwwroot add /js/print.js file and add

      window.print = function () { window.print(); window.close(); }

    7. To your main app CSS file (for me it is wwwroot/css/site.css) add the following:

    .print {
        display: none;
    }
    
    @media print {
        .no-print {
            display: none;
        }
    
        .print {
            display: block;
        }
    }
    
    1. To the wrapper div in first step, add print (it should be visible when printing) to other things that you want to exclude (such as side nav, top nav, main layout etc.) add no-print class

    Now on a click of button print preview should open and everything should be formatted nicely. Please expand on the answer if you have any other ideas.