Printing a section of a web page, but print out loses all styles?

2020-05-27 javascript html asp.net-mvc

I'm printing a section of my page from my MVC application with the following javascript code:

function PrintElem(elem) {
  Popup($(elem).html());
}

function Popup(data) {
  var mywindow = window.open("", "divprint", "height=400,width=600");
  mywindow.document.write("<html><head><title></title>");

  /*optional stylesheet*/
  // mywindow.document.write('<link rel="stylesheet" href="main.css" type="text/css" />'); 

  mywindow.document.write("</head><body >");
  mywindow.document.write(data);
  mywindow.document.write("</body></html>");
  cloneLinksAndStyle(window, newWindow);
  mywindow.document.close(); // necessary for IE >= 10
  mywindow.focus(); // necessary for IE >= 10

  mywindow.print();
  mywindow.close();

  return true;
}

HTML:

@model IEnumerable <AljawdahNewSite.Models.Orders_Tables>
  @{
   ViewBag.Title = "MasterDetails";
    Layout = "~/Views/Shared/_LayoutPatients.cshtml";
  }

  <h2>Order Result - نتائج التحاليل </h2>
  <table class="table table-bordered">
    <tr>
      <td style="text-align:center">
        <input type="submit" value="Print Result - طباعة النتيجة"
               onclick="PrintElem('#divprint')" class="btn btn-danger"/>
      </td>
    </tr>
  </table>
  <div id="divprint">
    <div style="margin-left:15px">
      <hr/>
      <dl class="horizontal">
        <dt style="width: 20%;display: inline-block;">@Html.DisplayNameFor(model
          => model.labViewResult.Patient_Name)
        </dt>
        <dd
          style="width: 25%;display: inline-block;margin: 0px;margin-left:-50px">
          @Html.DisplayFor(model =>
          model.FirstOrDefault().labViewResult.Patient_Name)
        </dd>
        <dt style="width: 22%;display: inline-block;">@Html.DisplayNameFor(model
          => model.labViewResult.Customer_Name)
        </dt>
        <dd
          style="width: 25%;display: inline-block;margin: 0px;margin-left:0px">
          @Html.DisplayFor(model =>
          model.FirstOrDefault().labViewResult.Customer_Name)
        </dd>
        <dt style="width: 20%;display: inline-block;">@Html.DisplayNameFor(model
          => model.labViewResult.Patient_No)
        </dt>
        <dd
          style="width: 25%;display: inline-block;margin: 0px;margin-left:-50px">
          @Html.DisplayFor(model =>
          model.FirstOrDefault().labViewResult.Patient_No)
        </dd>
        <dt style="width: 22%;display: inline-block;">@Html.DisplayNameFor(model
          => model.labViewResult.Clinic_File_No)
        </dt>
        <dd
          style="width: 20%;display: inline-block;margin: 0px;margin-left:0px">
          @Html.DisplayFor(model =>
          model.FirstOrDefault().labViewResult.Clinic_File_No)
        </dd>
        <dt style="width: 20%;display: inline-block;">@Html.DisplayNameFor(model
          => model.labViewResult.SEX)
        </dt>
        <dd
          style="width: 20%;display: inline-block;margin: 0px;margin-left:-50px">
          @Html.DisplayFor(model => model.FirstOrDefault().labViewResult.SEX)
        </dd>
        <dt style="width: 22%;display: inline-block;margin-left:60px">
          @Html.DisplayNameFor(model => model.labViewResult.Collection_Date)
        </dt>
        <dd
          style="width: 25%;display: inline-block;margin: 0px;margin-left:0px">
          @Html.DisplayFor(model =>
          model.FirstOrDefault().labViewResult.Collection_Date)
        </dd>
        <dt style="width: 20%;display: inline-block;">@Html.DisplayNameFor(model
          => model.labViewResult.AGE)
        </dt>
        <dd
          style="width: 20%;display: inline-block;margin: 0px;margin-left:-50px">
          @Html.DisplayFor(model => model.FirstOrDefault().labViewResult.AGE)
        </dd>
        <dt style="width: 22%;display: inline-block;margin-left:60px">
          @Html.DisplayNameFor(model => model.labViewResult.Receiving_Date)
        </dt>
        <dd
          style="width: 25%;display: inline-block;margin: 0px;margin-left:0px">
          @Html.DisplayFor(model =>
          model.FirstOrDefault().labViewResult.Receiving_Date)
        </dd>
        <dt style="width: 20%;display: inline-block;">@Html.DisplayNameFor(model
          => model.labViewResult.order_number)
        </dt>
        <dd
          style="width: 25%;display: inline-block;margin: 0px;margin-left:-50px">
          @Html.DisplayFor(model =>
          model.FirstOrDefault().labViewResult.order_number)
        </dd>

        <dt style="width: 22%;display: inline-block;">@Html.DisplayNameFor(model
          => model.labViewResult.Report_Date)
        </dt>
        <dd
          style="width: 25%;display: inline-block;margin: 0px;margin-left:0px">
          @Html.DisplayFor(model =>
          model.FirstOrDefault().labViewResult.Report_Date)
        </dd>


      </dl>
    </div>

    <div style="align-content:center">
      <table class="table table-bordered">
        <tr>

          <td> test name</td>
          <td> result</td>
          <td> From Range</td>
          <td> To Range</td>
          <td> Other Range</td>
          <td> Report Date</td>


        </tr>

        @foreach (var item in Model)
        {
        <tr>

          <td>@item.labViewResult.Test_Name</td>
          <td>@item.labViewResult.Result</td>
          <td>@item.labViewResult.Low_Range</td>
          <td>@item.labViewResult.High_Range</td>
          <td style="width:20%">@item.labViewResult.Text_Range</td>
          <td>@item.labViewResult.Report_Date</td>


        </tr>
        }
      </table>

      <link href="~/Contents/css/style.css" rel="stylesheet"/>
    </div>
  </div>

My issue is that when I print using javascript, the paper prints without any style. How can I add some style to my printout?

This is the current print out now.

(I'm new to JavaScript)

enter image description here

These are the CSS files I have linked in the shared layout:

<link
  href="https://fonts.googleapis.com/css?family=Oswald:400,700|Work+Sans:300,400,700"
  rel="stylesheet">
<link rel="stylesheet" [email protected]("/Contents/fonts/icomoon/style.css")>
<link rel="stylesheet" [email protected]("/Contents/css/bootstrap.min.css")>
<link rel="stylesheet" [email protected]("/Contents/css/magnific-popup.css")>
<link rel="stylesheet" [email protected]("/Contents/css/jquery-ui.css")>
<link rel="stylesheet" [email protected]("/Contents/css/owl.carousel.min.css")>
<link rel="stylesheet"
      [email protected]("/Contents/css/owl.theme.default.min.css")>
<link rel="stylesheet"
      [email protected]("/Contents/css/bootstrap-datepicker.css")>
<link rel="stylesheet" [email protected]("/Contents/css/animate.css")>

<link rel="stylesheet"
      [email protected]("/Contents/fonts/flaticon/font/flaticon.css")>

<link rel="stylesheet" [email protected]("/Contents/css/aos.css")>
<link rel="stylesheet" [email protected]("/Contents/css/style.css")>

Answers

I assume you have styling on the browser page that you want to maintain on the printout.

In order to maintain the same styles in the new window, you can copy the original window's link and style elements to the new window.

This function will copy all the link and style elements from one window to another:

function cloneLinksAndStyles (win, newWin) {
  const newHead = newWin.document.head;

  const links = Array.from(win.document.getElementsByTagName("LINK"));
  links.forEach(link => {
    let newLink = newWin.document.createElement('link');
    newLink.rel = 'stylesheet';
    newLink.href = link.href;
    newHead.appendChild(newLink);
  });

  const styles = Array.from(win.document.getElementsByTagName('STYLE'));
  styles.forEach(style => {
    let newStyle = newWin.document.createElement('style');
    newStyle.innerHTML = style.innerHTML;
    newHead.appendChild(newStyle);
  });
}

Then, in your script:

function Popup(data) {
  ...
  cloneLinksAndStyle(window, newWindow);
  ...
}

Here is a jsfiddle to show this working.

Related