2011-02-02 15 views
8

Ho una pagina html generata dinamicamente che è progettata per essere stampata.Utilizzo di CSS e/o jQuery per pagine stampate con interruzioni di pagina

vorrei creare interruzioni di pagina basati su sezioni DIV - in cui un dato div - se non lo fa in piena forma nella pagina, inserire un'interruzione di pagina prima di esso.

In teoria, ovunque da un singolo div, fino a forse 10, può adattarsi a una singola pagina stampata, quindi penso che sarà necessario utilizzare jQuery per gli inserimenti dopo il caricamento della pagina.

Se questa fosse un'applicazione desktop, vorrei avvicino qualcosa di simile:

  1. Misurare la (oggetto stampante utilizzando di qualche tipo) larghezza della pagina e l'altezza.
  2. Misurare ogni altezza div - e sottrarre che da pag totale rimanente altezza
  3. se (remaining_space - div_height> 0) {// metterlo a pagina} else {// Inserisci interruzione di pagina prima}

C'è un modo per usare jQuery, CSS, JavaScript raw o qualsiasi altra cosa, che mi porterebbe a questo scenario?

+0

Questa domanda è stata posta e ha già ricevuto varie risposte varie volte. Ecco un esempio: http://stackoverflow.com/questions/4760899/page-break-beforeauto-not-working-for-me-why/ – mVChr

+0

sì - ho verificato che già uno, in realtà non risponde alla mia domanda, però, ma è un passo. Grazie. – OneNerd

risposta

3

Ok, ho passato il giorno passato o così capire questo fuori, così ho voluto pubblicare la mia soluzione a questo nel caso in cui nessun altro necessaria la risposta.

In generale qui è quello che ho fatto.

  1. output generato come normale (non stampante improprio)
  2. Creato 2 fogli di stile (uno per stampante e uno per lo schermo). Le misure erano espresse in pollici (non in pixel) per tutti gli elementi della pagina da trasformare in output stampato.
  3. utilizzando jQuery, ho fatto la seguente:

-> chiamato funzione che aggiunge la pagina iniziale per DOM - qualcosa di simile

// assumes old_page_id is existing element in DOM, and var page_id = 1; 
$j("<div class='page' id='" + page_id + "'><div class='print_area'></div></div>") 
.insertAfter('#' + old_page_id); 

- altezza> misura del div che è la pagina (in il mio caso, $ ('pagina') altezza();.)

-> corse una funzione per fare gli inserimenti di div e nuove pagine - qualcosa di simile

$('div_class').each(
function() { 
    // measure height of $(this) 
    // add it to running total of used space on existing page 
    // if sum total exceeds remaining space, create new page, and add to that one 
    // if still room left, add to this one 
} 
); 

Nota che ogni pagina div (nel mio caso, class = 'Pagina') nel foglio di stile stampante è dotata di questo:

page-break-after: sempre;

Ecco come sono riuscito a creare una nuova pagina sulla stampante dove volevo.

Dopo aver eseguito la funzione jQuery sopra, ho nascosto la sezione originale che conteneva elementi div che volevo spostare nelle pagine stampate. Nota Non ho potuto nascondere questa sezione in anticipo perché le mie misurazioni di jQuery non avrebbero prodotto risultati validi (nel mio caso, ho inserito tutti i div all'interno di un wrapper div con ID di 'hide_me' e imposta lo stile su altezza: 1px overflow: auto;).

Mi rendo conto che questa è una vista di 50.000 piedi, ma spero che sia utile per voi.

2

Si può sempre inserire un tag DIV vuoto con il l'attributo CSS {pageBreakBefore: 'sempre'} o {pageBreakAfter: 'sempre'} a punti nella vostra HTML in cui è stato calcolato in jQuery i bordi della pagina per essere ispezionando l'altezza dei DIV o qualsiasi altra cosa. Ma avresti bisogno di avere una conoscenza abbastanza intima del contenuto della pagina e probabilmente specificare le dimensioni del tuo carattere ecc. Come "pt" invece di "px".

Vedere una query simile qui però:

Enforce Print Page Breaks with CSS

0

Non è esattamente quello che stai cercando, ma hanno uno sguardo a questo http://www.javascriptkit.com/dhtmltutors/pagebreak.shtml

Con un pizzico ulteriore di JS , può essere possibile ciò che vuoi provare a raggiungere.

+0

sì, lo stavo leggendo prima di postare qui. È un passaggio, ma poiché potrei avere più div in una pagina, la soluzione non funzionerebbe per me. Grazie comunque. – OneNerd

0

Si potrebbe provare a utilizzare questo plugin per stampare gli elementi di una pagina. http://www.recoding.it/wp-content/uploads/demos/jqprint-demo.htm

Questo potrebbe essere utile se si segue la stessa logica che ha suggerito per un'applicazione desktop. Puoi avvolgere le tue "pagine" in div e questo è ciò che diresti a jqPrint di stampare. Le interruzioni di pagina potrebbero essere un altro elemento o anche un div, ma con una classe per farti sapere che è l'interruzione di pagina. Per esempio:

<div id="#page1" class="page"> 
... 
</div> 
</div id="#break1" class="break"> </div> 

ecc ..

poi

$('#page1').jqprint(); 

non so se si ha familiarità con jQuery. Se non lo facci sapere.

+0

Io uso jquery, ma non ho familiarità con la funzione jqprint() - è qualcosa che hai aggiunto? – OneNerd

+0

@OneNerd - Hai ragione non è jQuery, ho dimenticato di aggiungere il link al plugin. Eccolo: http://www.recoding.it/wp-content/uploads/demos/jqprint-demo.htm –

0

Il punto di impaginazione, nella mia mente, è quello di non dividere le cose male. E di solito, ciò che si desidera non dividere più male è il dato tabellare. Quindi questo è un approccio che presume che tu abbia modificato la formattazione della tabella in <div> e che abbia raggruppato i gruppi di righe che non dovrebbero essere suddivisi nei raggruppamenti <tbody>.

Vogliamo segnare intestazioni e piè di pagina per il codice da trovare, e non necessariamente desidera vengano visualizzati a destra dove sono descritti

Questo si invoca al caricamento della pagina, ma potrebbe invece essere chiamati a destra prima della stampa .

<script> 
    $().ready(function() { 
     $('table.paged').each(function (i, o) { 
      BreakPages($(o)); 
     }) 
    }); 
    function BreakPages(jSource) { 
     $('body').width("7in"); 
     var perInch = $('body').width()/7.5; 
     var nPageHeight = 9 * perInch; 

     var jHeader = null; 
     var jFooter = null; 
     var jWrapper = jSource.clone().empty(); 
     var jPage = null; 
     var iPage = 0; 
     jSource.after("<div></div>"); 
     var jFixed = jSource.next(); 

     function substed(jStuff) { 
      var jCopy = jStuff.clone(); 
      jCopy.find('span.pageNo').html(" " + iPage + " ").removeClass('pageNo'); 
      return jCopy; 
     } 

     jSource.children().each(
      function (iChunk, oChunk) { 
       var jChunk = $(oChunk); 
       if (jChunk.hasClass('footer')) { 
        jFooter = jChunk; 
       } 
       if (jChunk.hasClass('header')) { 
        jHeader = jChunk; 
        jFooter = jChunk.nextUntil('.footer').last().next(); 
       } 
       if (!jChunk.hasClass('sample')) { 
        var nHeight = jChunk.height(); 
        if (jPage) 
         nHeight += jPage.height(); 
        if (jFooter) 
         nHeight += jFooter.height(); 
        if (nHeight > nPageHeight) { 
         if (jFooter) 
          jPage.append(substed(jFooter)); 
         jPage.after("<p style='page-break-after:always; height:0; width:0'>&nbsp</p>"); 
         jPage = null; 
        } 
        if (!jPage) { 
         iPage++; 
         jPage = jWrapper.clone(); 
         jFixed.append(jPage); 
         if (jHeader && jHeader !== jChunk) 
          jPage.append(substed(jHeader)); 
        } 
        jPage.append(jChunk); 
       } 
      } 
     ); 
     jFixed.find('span.pageCount').html(" " + iPage + " "); 
     jFixed.find('span.pageNo').html(" " + iPage + " "); 
     jSource.remove(); 
    } 
</script> 

Disponiamo il tavolo da impaginare in questo modo.

<body> 
    <table> 
     <tbody class="header"> 
      PAGE ONE HEADER 
     </tbody> 
     <tbody class="header sample"> 
      LATER PAGE HEADER (IF RELEVANT) 
     </tbody> 
     <tbody class="together"> 
      ROW GROUP 1 
     </tbody> 

     <tbody class="together"> 
      ROW GROUP N 
     </tbody> 
     <tbody class="footer"> 
      FOOTER 
     </tbody> 
    </table> 
</body> 

Abbiamo eseguire la scansione in 's <tbody> e roba un piè di pagina e un colpo di testa prima di ogni elemento che è destinato a rompere attraverso la fine di una pagina.

Contrassegniamo intestazioni e piè di pagina con classi css e teniamo traccia della possibilità di cambiare intestazioni e piè di pagina posizionandoli nelle posizioni nel flusso di riga in cui devono essere modificati, ma mantenendoli invisibili con un'altra classe css.

Annoyingly alcune implementazioni di interruzione di pagina si applicano solo agli elementi strettamente "blocco", quindi non è definito su tbody. Quindi l'ho applicato ad una classe di tag <p> aggiunta ad ogni tabella di pagina.

Problemi correlati