Imprimindo elementos com o VueJS usando bibliotecas de terceiros

14

Estou trabalhando na tabela HTML e, imprimindo essa tabela na impressora usando o html-to-papervue.js. O que estou fazendo é clicar em adicionar, criar uma nova linha e, em seguida, clicar em imprimir. Estou tentando imprimir a tabela, mas ela não está sendo usada. quaisquer dados mostrando apenas células vazias

Code 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");

aqui o código de trabalho em codesandbox

Verifique o código em execução

Editar conforme a recompensa

eu tenho que fazer isso com 'html-to-paper', o problema é que não consigo dar estilo aos meus elementos para impressão usando @media print

  • A resposta ux.engineeré boa, mas o problema do navegador crome e o firefox o bloqueiam devido a problemas de segurança

Por favor, verifique a caixa de areia de código, por exemplo, aqui está o meu código completo, estou tentando dar um estilo, mas não está acontecendo

  • O html-to-printplug-in usa window.open; portanto, quando clico em imprimir, não leva o estilo para a nova página.
  • É aí que eu estou preso, porque não está assumindo o estilo de mídia, como posso substituir meu estilo na janela.open

Eu estava usando o print-nb Mas não está funcionando no navegador devido a algum motivo de segurançaé isso que diz ao usar o print-nb

manish thakur
fonte
manish thakur, verifique minha nova resposta (o período de carência para recompensa termina em 4 horas, após o qual será desperdiçado se não for concedido)
ux.engineer
stackoverflow.com/help/bounty
ux.engineer 16/01

Respostas:

9

Infelizmente, você não pode aproveitar a ligação de dados do Vue com este pacote mixin mycurelabs / vue-html-to-paper , conforme indicado aqui pelo autor do pacote .

No entanto, criei uma solução alternativa alternando o pacote usado aqui para a diretiva Power-kxLee / vue-print-nb .

Aqui está um exemplo de trabalho: https://codesandbox.io/s/zen-sunset-2szqr

PS. Escolher entre pacotes semelhantes pode ser complicado às vezes. Deve-se avaliar as estatísticas de uso e atividade do repositório, como: Usado por, Observar e Iniciar na primeira página, depois verificar problemas em aberto / fechado e solicitações de recebimento ativo / fechado e, em seguida, acessar Insights para verificar o pulso (1 mês) e Frequência de código.

Entre esses dois, eu escolheria o vue-print-nb por ser mais popular e usado ativamente. Também porque eu preferiria usar uma diretiva em vez de um mixin .

No que diz respeito à outra resposta, manter o uso do vue-html-to-paper para esse fim precisaria desse tipo de solução hacky ... Onde esta diretiva funciona imediatamente.

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

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

ux.engineer
fonte
11
Não sei como esses pacotes de impressão se comparam, mas se estiver tudo bem em trocar de pacote, acho que essa é uma solução melhor do que minha solução alternativa com espaços reservados.
Arkuuu
@ ux.engineer como achei sua idéia muito simples e limpa, eu tenho uma dúvida (problema) aqui quando estou imprimindo a tabela que está imprimindo página inteira com inputsinterior que não é bom, quero remover essa entrada e ser ela como campo normal, também posso gerenciar a altura, porque estou usando o USB Printerque não está tendo folhas a4.
manish thakur 19/12/19
@manishthakur você pode usar o estilo global de CSS com impressão de segmentação de consulta de mídia, aqui está um exemplo de trabalho: codesandbox.io/s/ecstatic-fire-zo2b2
ux.engineer
Ok, está funcionando, então por isso eu posso definir o cs, o problema aqui é suponha que quatro linhas estejam lá, mas a impressora está imprimindo uma impressora completa, eu estou usando uma impressora USB que é usuário para imprimir contas, por favor, esclareça isso para mim
perfil completo de manish thakur
@manishthakur que tal isso: codesandbox.io/s/charming-sound-7h1bg - usando @pageregra CSS ( developer.mozilla.org/en-US/docs/Web/CSS/@page ) como explicado aqui stackoverflow.com/questions / 44064707 /…
ux.engineer
6

Como outros já mencionaram, isso não é possível com o pacote que você usa, porque os dados encadernados v-modelnão existem durante a impressão. Portanto, você precisa obter esses dados estaticamente dentro do seu html. Fonte

Uma solução alternativa seria usar espaços reservados de entrada:

Adicione uma referência à sua tabela:

<tbody ref="tablebody">

Isso permite que você selecione esse elemento no seu método. Agora mude o método de impressão:

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 = "";
  }
}

Então talvez estilize os espaços reservados com css, porque parece cinza por padrão.

Primeiro tentei redefinir o valor da entrada, como input.value = input.value, mas infelizmente isso não funcionou.

Atualizou seu código aqui

arkuuu
fonte
11
Uma solução inteligente, embora um pouco hacky. Mas parece necessário se alguém quiser usar esse mix Vue específico para imprimir valores dinâmicos como este. No entanto, neste ponto, eu procuraria por pacotes alternativos.
Ux.engineer
@arkuuu Verifique minha parte de edição sempre que estiver livre.
manish thakur
@manishthakur Eu li, mas não faço ideia. Talvez você possa incluir as regras de css de impressão em um arquivo css separado e usar a stylesopção vue-html-to-paper como fez com as outras folhas de estilo.
arkuuu 8/01
11
Eu tentei isso, mas nada mudou, ainda não está tomando estilos
manish thakur 09/01
0

De acordo com sua nova recompensa na questão, por continuar usando vue-html-to-paper, aqui está um exemplo de código atualizado para carregar a folha de estilo externa na janela de impressão .

Primeiro ele carrega os estilos de Bootstrap de uma CDN externa e, em seguida, um arquivo CSS local do diretório público. Esta folha de estilo local possui apenas um estilo para usar a !importantsubstituição da cor de fundo da entrada para verde.

O Chrome no Windows aplica esse estilo de plano de fundo verde às entradas se gráficos de plano de fundo da opção de impressão forem aplicados. O Firefox no Windows possui um painel de opções de impressão diferente, que não possui essa configuração.

No entanto, ambos estão aplicando estilos de Bootstrap pelo menos parcialmente, para que as folhas de estilo sejam carregadas e em jogo.

Esse problema de entrada em estilo de plano de fundo era para demonstrar diferenças em como os navegadores lidam com os estilos de impressão, e é um tópico mais amplo fora do escopo desta pergunta.

PS. Não sei ao certo que tipo de problema de segurança havia no vue-print-nbpacote, mas talvez ele possa ser resolvido. Você deve abrir um problema no repositório Github com um exemplo mínimo de reprodução de erros.

Adicionando esta resposta como uma entrada separada se vue-print-nbo problema dessa solução for resolvido posteriormente e minha resposta for atualizada.

ux.engineer
fonte
Ei, eu estou verificando se não está usando estilos perfeitamente, pois estou tentando remover, input fields mas está usando todos eles.
manish thakur 16/01
Não está claro quais estilos você está tentando aplicar ... Como dito, os estilos não são impressos da mesma maneira que no navegador, pois há restrições. E mesmo aqueles variam entre os navegadores / plataformas. Mas a folha de estilo do Bootstrap é aplicada , não é? E minha substituição, para que os estilos sejam carregados?
ux.engineer 16/01
Não, estou removendo os campos de entrada, mas não está removendo, pois quero remover o campo de entrada e mostrá-lo como tabela basich com algum estilo que desejo fornecer na impressão, ou seja, tamanho e alinhamento da fonte, mas não está levando, estou escondendo uma coluna também, mas na impressão está pegando todos eles
manish thakur 16/01
Ei, você pode adivinhar qual é o problema, print-nbpois esse é o melhor para se trabalhar, mas eu não sei por que o navegador não permite css
manish thakur