Generate several invoices with just a single click using TypeScript

I'm interested in efficiently printing multiple custom HTML invoices with just one click, similar to this example:

Although I attempted to achieve this functionality using the following method, it appears to be incorrect as it prompts the print dialog multiple times:

printInvoices() {
    this.orders.forEach(order => {
      let content = `
      <head>
    <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="395b56564d4a4d4b4b2f6669666562612763040c55010104063e">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
    <style>
        @media print {
            .invoice {
                font-size: 11px !important;
                overflow: hidden !important
            }
        }
    </style>
</head>

<body>
—

</body>
      `;

      let newWindow = window.open("", "", "width=300,height=300");
      newWindow?.document.write(content);
      newWindow?.focus();
      newWindow?.print();
      newWindow?.close();
    });
  }

Any suggestions on how to accomplish this task more effectively?

Answer №1

If you want to display all your invoices on one page in blocks, you can achieve this by using the CSS property page-break-after: always; to split these blocks into multiple pages.

Here's an example:

document.getElementById('printBtn').addEventListener('click', () => {
  window.print();
});
.pages {
  display: none;
}

@media print {
  #printBtn {
    display: none;
  }
  @page {
    margin: 0;
  }
  .pages {
    page-break-after: always;
    display: block;
  }
}
<div class="container">
  <div class="pages">
    <h1>One</h1>
  </div>
  <div class="pages">
    <h1>Two</h1>

  </div>
  <div class="pages">
    <h1>Three</h1>
  </div>
</div>

<button id="printBtn">Print me</button>

Using multiple instances of window.print() will trigger the print dialog multiple times for each block created.

Answer №2

Chances are, the best way to tackle this issue is by combining several PDFs directly on the server and then printing the consolidated document in one go.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Locate all buttons on the page that have an onclick function attached to them, and

I seem to have run into an issue. I am currently working with Java and WebDriver. My goal is to navigate to , locate the item "ipod", receive 4 results, and then compare them by clicking on the "compare" button beneath each item. However, I am encounteri ...

What could be causing my selenium tests to fail on travis-ci even though there have been no code changes, when they are passing successfully

I'm facing a tough challenge trying to troubleshoot a selenium test that passes when run locally but not on travis. Reviewing the travis build logs, I noticed that the test was passing in build #311 but started failing at build #312. It seems like th ...

Display numerous occurrences of a certain class by utilizing a different class

I'm currently in the process of creating a board game similar to Ludo, which requires a grid of 13x13 squares. I've created a Box class that successfully renders a single square button. Here's the code: class Box extends React.Component{ r ...

Vue.js - A dynamic parent component generates content based on data passed from a renderless child component

I am currently working on developing a system for generating buttons using vue 3 and vue-class-component. The main goal is to create a flexible button generation process, where the number of buttons generated can vary (it could be just one or multiple). Us ...

Fine-tuning the flexbox grid layout for various screen sizes, both big and small

Two different layouts were created. The first layout is designed for medium & large screens, while the second one is tailored for devices with a maximum width of 736px. Check out the vanilla implementation using flexbox (without mobile adaptation) Here ...

Having difficulties in accessing an API with Ionic 3

Whenever I attempt to connect with an API, I keep encountering the Cross-Origin Read Blocking (CORB) blocked cross-origin response error. Can anyone provide guidance on how to resolve this issue? Any assistance would be greatly appreciated. ...

What is the best way to find the maximum and minimum values within a JSON object that is populated from user inputs using only JavaScript?

Here is a simple form that stores data at the following link: https://jsfiddle.net/andresmcio/vLp84acv/ var _newStudent = { "code": code, "names": names, "grade": grades, }; I'm struggling to retrieve the highest and lowe ...

Implementing Constants in Angular 2: Best Practices

Within my Angular 2 project, I have a crucial object known as translation that stores various strings utilized in multiple forms. This global configuration appears as follows: public translator = { 'performance_standard_time_deviation&apo ...

Angular threw an error saying: "Template parse errors: is not a recognized element"

I am attempting to utilize babel standalone within a react application to transpile Angular TypeScript. The transpiling process seems to be successful, however, I encounter an error when trying to import a component and use its selector within the template ...

What is the process for extracting data from a canvas tag and why does it appear invisible on my browser?

The highlighted area in this image contains the HTML content and the red circle marks the section to be scraped The phone number can be found within the canvas tag. However, when trying to scrape the tag, it shows "Your browser does not support the HTML5 c ...

Height of Hover Background Color in WordPress Menu

Greetings! Welcome to my website I'm in the process of modifying the hover color for the top menu, and I've managed to change it successfully. However, I would like the hover effect to cover the entire height of the menu, as right now it's ...

"Encountering a hang while using the .save() function and only

Issue with storing data in MongoDB This is only my second attempt at saving data to a database and I am still relatively new to the process. I have a form on my HTML page that sends string data to be saved in a MongoDB database. I successfully connected t ...

What is the best way to transfer global Meteor variables to templates and effectively utilize them?

I am in the process of developing a compact, single-page application game that emulates the dynamics of the stock market. The price and behavior variables are influenced by various factors; however, at its core, there exists a finite set of universal varia ...

Angular elements nested within each other are causing the ExpressionChangedAfterItHasBeenCheckedError

After conducting thorough research on this issue, I am now uncertain whether it is a bug or an error in my implementation. The problem arises with an element that utilizes a service to retrieve data and then passes it on to a child element. However, upon ...

What is the best way to evaluate typing into an input field?

My objective is to test the 'typing' functionality in an input element. The aim is to insert a value into the input element, verify that its binding successfully captures the value, and observe the entered value within the input element. Below i ...

Is it possible to transfer the reactivity of a Vue ref to another ref while reassigning it?

Below is a simplified version of my Vue component: <template> <div @click="loadEvents">{{ loading }}</div> </template> <script setup> import { ref } from 'vue' let loading = ref(false) loadEvents() func ...

Enhancing a class's properties from its parent component using React

Recently, I decided to dive into React by taking on the challenge of rebuilding the Google Weather app. My main objective is to have the main section update whenever a day is selected. Initially, I believed that updating the props within handleSelectionAt( ...

Having trouble importing Material UI and working with ClickAwayListener

For my current project, I am utilizing material-ui to implement the functionality for changing passwords. In this root file, I am importing several child components: Personalize.js import React, { useContext, useState } from 'react'; import Cook ...

Determine the position of the cursor in an editable span

Is there a way to add text at the cursor position in an editable span when a button is clicked? The span contains multiple lines of text and HTML tags. [Take a look at this example on JSFiddle](http://jsfiddle.net/8txz9sjs/) ...

Is there a way to adjust the orientation of a <video> element without affecting the orientation of the video controls?

<video controls> </video> video { transform: scaleX(-1) } This CSS code flips the video horizontally, but it also flips the control buttons along with it. I attempted to flip the wrapper element containing the video using .wrapper {transfor ...