Imprimir elementos con VueJS utilizando bibliotecas de terceros

14

Estoy trabajando en la tabla HTML e imprimiendo esa tabla en la impresora usando html-to-papervue.js, lo que estoy haciendo es hacer clic en agregar creando una nueva fila y luego en hacer clic en imprimir Estoy tratando de imprimir la tabla pero no está tomando cualquier dato que solo muestre celdas vacías

Código App.vue

    <template>
  <div id="app">
    <button type="button" @click="btnOnClick">Add</button>

    <div id="printMe">
      <table class="table table-striped table-hover table-bordered mainTable" id="Table">
    <thead>
      <tr>

        <th class="itemName">Item Name</th>
        <th>Quantity</th>
        <th>Selling Price</th>
        <th>Amount</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(tableData, k) in tableDatas" :key="k">

        <td>
          <input class="form-control" readonly v-model="tableData.itemname" />
        </td>
        <td>
          <input class="form-control text-right" type="text" min="0" step=".01" v-model="tableData.quantity" v-on:keyup="calculateQty(tableData)" />
        </td>
        <td>
          <input class="form-control text-right" type="text" min="0" step=".01" v-model="tableData.sellingprice" v-on:keyup="calculateSPrice(tableData)" />
        </td>
        <td>
          <input readonly class="form-control text-right" type="text" min="0" step=".01" v-model="tableData.amount" />
        </td>
      </tr>
    </tbody>
  </table>
    </div>
    <button @click="print">Print</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableDatas: []
    }

  },
  methods: {
    btnOnClick(v) {
      this.tableDatas.push({
        itemname: "item",
        quantity: 1,
        sellingprice: 55,
        amount: 55
      });
    },
     print() {
      this.$htmlToPaper('printMe');
    }
  }
};
</script>

<style>
</style>

main.js

 import Vue from "vue";
import App from "./App.vue";
import VueHtmlToPaper from "vue-html-to-paper";

Vue.config.productionTip = false;
Vue.use(VueHtmlToPaper);

new Vue({
  render: h => h(App)
}).$mount("#app");

aquí el código de trabajo en codesandbox

Por favor verifique el código de ejecución

Editar según la recompensa

tengo que hacerlo con 'html-to-paper' el problema es que no puedo dar estilo a mis elementos para imprimir usando @media print

  • La respuesta ux.engineerestá bien, pero al causar problemas de navegador, Chrome y Firefox lo están bloqueando debido a problemas de seguridad.

Comprueba el código sandbox, por ejemplo, aquí está mi código completo, estoy tratando de dar estilo pero no sucede

  • El html-to-printcomplemento usa window.open, de modo que cuando hago clic en imprimir no lleva el estilo a una nueva página.
  • Ahí es donde estoy atrapado, por qué no está tomando estilo de medios, ¿cómo puedo anular mi estilo en la ventana?

Estaba usando print-nb Pero no funciona en el navegador debido a alguna razón de seguridadesto es lo que se dice al usar print-nb

thakur viril
fuente
manish thakur, por favor revisa mi nueva respuesta (el período de gracia de recompensa termina en 4 horas, en el que se desperdiciará si no se otorga)
ux.engineer

Respuestas:

9

Lamentablemente, no puede aprovechar el enlace de datos de Vue con este paquete mixcure mycurelabs / vue-html-to-paper , como lo indica aquí el autor del paquete .

Sin embargo, he creado una solución alternativa al cambiar el paquete utilizado aquí a la directiva Power-kxLee / vue-print-nb .

Aquí hay un ejemplo de trabajo: https://codesandbox.io/s/zen-sunset-2szqr

PD. Elegir entre paquetes similares puede ser complicado a veces. Uno debe evaluar las estadísticas de uso y actividad del repositorio como: Usado por, Ver y Comenzar en la página principal, luego verificar Problemas abiertos / cerrados y Solicitudes de extracción activas / cerradas, y luego ir a Insights para verificar Pulse (1 mes), y Código de frecuencia.

Entre estos dos, elegiría vue-print-nb para ser más popular y utilizado activamente. También porque preferiría usar una directiva sobre un mixin .

En lo que respecta a la otra respuesta, seguir usando vue-html-to-paper para este propósito necesitaría ese tipo de solución extravagante ... Donde esta directiva funciona fuera de la caja.

https://github.com/mycurelabs/vue-html-to-paper

https://github.com/Power-kxLee/vue-print-nb

ux.engineer
fuente
1
No sé cómo se comparan estos paquetes de impresión, pero si está bien cambiar de paquetes, creo que esta es una mejor solución que mi solución alternativa con marcadores de posición.
arkuuu
@ ux.engineer, ya que encontré que su idea es muy simple y limpia, tengo una duda (problema) aquí cuando imprimo la tabla, imprime la página completa con el inputsinterior, lo que no es bueno, quiero eliminar esa entrada y ser Al igual que el campo normal, también puedo manejar la altura, porque estoy usando una USB Printerque no tiene 4 hojas.
manish thakur
@manishthakur puede usar un estilo CSS global con impresión de orientación de consulta de medios, aquí hay un ejemplo de trabajo: codesandbox.io/s/ecstatic-fire-zo2b2
ux.engineer
Ok, está funcionando, así que con esto puedo definir el cs, el problema es aquí, supongamos que hay cuatro filas allí, pero la impresora está imprimiendo una impresora de larga duración, estoy usando una impresora USB que es usuario para imprimir facturas, por favor aclare esto
manish thakur
@manishthakur, ¿qué tal esto: codesandbox.io/s/charming-sound-7h1bg - usando @pageCSS-rule ( developer.mozilla.org/en-US/docs/Web/CSS/@page ) como se explica aquí stackoverflow.com/questions / 44064707 / ...
ux.engineer
6

Como otros han mencionado, esto no es posible con el paquete que usa, porque los datos vinculados de v-modelno existen al imprimir. Por lo tanto, debe obtener esta información estáticamente dentro de su html. Fuente

Una solución alternativa sería utilizar marcadores de posición de entrada:

Agregue una referencia a su tabla:

<tbody ref="tablebody">

Esto le permite seleccionar este elemento en su método. Ahora cambie el método de impresión:

print() {
  const inputs = this.$refs.tablebody.getElementsByTagName("input");
  for (let input of inputs) {
    input.placeholder = input.value;
  }
  this.$htmlToPaper("printMe");
  for (let input of inputs) {
    input.placeholder = "";
  }
}

Entonces, tal vez diseñe los marcadores de posición con css, porque se ve gris por defecto.

Primero intenté de alguna manera restablecer el valor de la entrada input.value = input.value, pero desafortunadamente eso no funcionó.

Actualizó su código aquí

arkuuu
fuente
1
Una solución inteligente, aunque poco hacky. Pero parece necesario si a uno le gustaría seguir usando este particular Vue mixin para imprimir valores dinámicos como este. Sin embargo, en este punto buscaría paquetes alternativos.
ux.engineer
@arkuuu Por favor revisa mi parte de edición siempre que estés libre.
Manish thakur
@manishthakur Lo leí pero no tengo idea. Tal vez podría incluir poner sus reglas css de impresión en un archivo css separado y usar la stylesopción de vue-html-to-paper como lo hizo con las otras hojas de estilo.
Arkuuu
1
He intentado eso pero nada ha cambiado, aún así no está tomando estilos
manish thakur
0

Según su nueva recompensa sobre la pregunta, para seguir usando vue-html-to-paper, aquí hay un ejemplo de código actualizado para cargar la hoja de estilo externa en la ventana de impresión .

Primero carga los estilos Bootstrap de un CDN externo, luego un archivo CSS local del directorio público. Esta hoja de estilo local solo tiene un estilo para usar la !importantanulación para el color de fondo de entrada a verde.

Chrome en Windows aplica ese estilo de fondo verde a las entradas si se aplica la opción de imprimir gráficos de fondo . Firefox en Windows tiene un panel de opciones de impresión diferente, que no tiene esa configuración.

Sin embargo, ambos aplican estilos Bootstrap al menos en parte, por lo que las hojas de estilo se cargan y están en juego.

Este problema de estilo de fondo de entrada fue para demostrar diferencias en cómo los navegadores manejan los estilos de impresión, y es un tema más amplio fuera del alcance de esta pregunta.

PD. No estoy seguro de qué tipo de problema de seguridad hubo con el vue-print-nbpaquete, pero tal vez podría resolverse. Debería abrir un problema en su repositorio de Github con un ejemplo de reproducción mínima de errores.

Agregar esta respuesta como una entrada separada si vue-print-nbel problema de esa solución se resuelve más tarde y mi respuesta se actualiza.

ux.engineer
fuente
Hola, estoy comprobando que no está tomando estilos perfectamente, ya que estoy tratando de eliminarlos, input fields pero los está tomando todos.
Manish thakur
No está claro qué estilos está tratando de aplicar ... Como se dijo, los estilos no se imprimen de la misma manera que en el navegador, ya que existen restricciones. E incluso esos varían entre los navegadores / plataformas. Pero la hoja de estilo Bootstrap se aplica , ¿no? Y mi anulación, ¿se cargan los estilos?
ux.engineer
No, estoy eliminando los campos de entrada, pero no está eliminando, ya que quiero eliminar el campo de entrada y mostrarlo como una tabla básica con un estilo que quiero dar en la impresión, es decir, tamaño de fuente y alineación, pero no está tomando, me estoy ocultando una columna también, pero en la impresión los está tomando a todos
manish thakur
Oye, ¿puedes adivinar cuál es el problema print-nbya que es el mejor con el que trabajar, pero no sé por qué el navegador no permite css?
Manish thakur