2011-03-13 21 views
7

ben soyut bir yöntem beraberlik (Graphics2D g2) ile soyut bir sınıf var ve yöntemler baskı nasıl oluşturulur(), showPreview(), printPDF(). Java programımdaki her bir belge için draw() uygularım, böylece her bir belge için baskı yapabilir, önizleme yapabilir ve bir PDF dosyası oluşturabilirim. Sorunum, o Graphics nesnesinden birden fazla sayfa içeren bir PDF oluşturma. Her sayfa için bir PDF dosyası oluşturarak çözdüm ve dosyaları yeni bir dosyaya birleştir. Ama daha iyi bir yol olmalı. Yani tüm arayüz N kez render ediyoruzbir Java ile Grafik nesneden birden fazla sayfa ile PDF ve iText

public void printPDF1(){ 
    JFileChooser dialog = new JFileChooser(); 
    String filePath = ""; 
    int dialogResult = dialog.showSaveDialog(null); 
    if (dialogResult==JFileChooser.APPROVE_OPTION){ 
     filePath = dialog.getSelectedFile().getPath(); 
    } 
    else return; 
    try { 
     Document document = new Document(new Rectangle(_pageWidth, _pageHeight)); 
     PdfWriter writer = PdfWriter.getInstance(document, 
       new FileOutputStream(filePath)); 
     document.open(); 

     PdfContentByte cb = writer.getDirectContent(); 
     g2 = cb.createGraphics(_pageWidth, _height); 
     g2.translate(0, (_numberOfPages - _pageNumber) * _pageHeight); 
     draw(g2); 
     g2.dispose(); 
     document.close(); 
    } 
    catch (Exception e2) { 
     System.out.println(e2.getMessage()); 
    } 
} 

cevap

9
document.open(); 

    // the same contentByte is returned, it's just flushed & reset during 
    // new page events. 
    PdfContentByte cb = writer.getDirectContent(); 

    for (int _pageNumber = 0; _pageNumber < _numberofPages; ++_numberOfPages) { 
     /*******************/ 
     //harmless in first pass, *necessary* in others 
     document.newPage(); 
     /*******************/ 

     g2 = cb.createGraphics(_pageWidth, _height); 
     g2.translate(0, (_numberOfPages - _pageNumber) * _pageHeight); 
     draw(g2); 
     g2.dispose(); 
    } 

    document.close(); 

ve yalnızca farklı yerlerde bunun bir sayfa büyüklüğünde dilim gösterilen: Ben kod tek sayfayla PDF oluşturmak için aşağıdaki var. Buna baskı dünyası IIRC'de "şeritleme" denir. Zeki, ancak PDF'de daha verimli olabilir.

kez (G2D ile) bir dev PdfTemplate içine tüm arayüz Render. Ardından, bu şablonu tüm sayfalarınıza çekin, böylece istediğiniz sayfanın geçerli sayfa kenar boşluklarında ("medya kutusu") görünmesi sağlanır. koordinat alanını

PdfContentByte cb = writer.getDirectContent(); 
float entireHeight = _numberOfPages * _pageHeight; 
PdfTemplate hugeTempl = cb.createTemplate(0, -entireHeight, pageWidth, _pageHeight); 
g2 = hugeTempl.createGraphics(0, -entireHeight, _pageWidth, _pageHeight); 
draw(g2); 
g2.dispose(); 

for (int curPg = 0; curPg < _numberOfPages; ++curPg) { 
    cb.addTemplateSimple(hugeTempl, 0, -_pageHeight * curPg); 

    document.newPage(); 
} 

PDF sol alt köşesinde 0,0 ayarlar ve yukarı çıkıp sağa olarak bu değerler artar. PdfGraphis2D senden bu farkı gizlemek için sihirli adil bir miktar yapar, ama biz hala bu şekilde sınırlama kutusuna negatif koordinatlar ve çizim yerleri ... Onunla burada biraz uğraşmak zorunda.

Bu, tüm "peçetenin geri" kodlama edilir ve ben bir hata ya da orada ikisini yaptık tamamen mümkün ... ama bu fikir. Yukarıdaki kod aşağıdaki zorluk çektiğini

+0

Çok teşekkürler, aşağıdaki değişikliklerle çalışır. – Jan

+0

Hangi değişiklikler? Not: Bu, doğru cevabın yanındaki diğer onay işaretlerini tıklattığınız, diğer kişilerin kimlerin doğru olduğunu bilmesini sağlayan (ve bu kişiye bir itibar kazandıran) kısımdır. Bu durumda "Ben". Ayrıca, birden fazla soru soruyor ve yanıtlamalarını hiçbir zaman işaretlemezseniz, diğer kişiler, yanlış yanıtlanmış yüzdesini görecekler ve haklı olduklarında bile onlara rötuş yapamayacağınızı bildiğinden daha az rahatsızlık duyacaklardır. –

+0

Üzgünüz Mark, Bu web sitesinin nasıl çalıştığını anlamaya çalışıyorum. PdfContentByte'ın her sayfa için yeniden kullanılabileceğini anlayamadım. thes değişiklik yapılmış: PdfTemplate şablonu = cb.createTemplate (_pageWidth, entireHeight); g2 = template.createGraphics (_pageWidth, entireHeight); ..... (int curPg = 1; curPg <= _numberOfPages; ++ curPg) { cb.addTemplate (hugeTempl, 0, -_pageHeight * (_numberOfPages - curPg)); document.newPage(); } – Jan

0

(yöntemlerden bazıları güncel itextpdf sürümünde değişmiş gibi görünen). İşte benim çözümüm:

import com.itextpdf.awt.PdfGraphics2D; 
import com.itextpdf.text.Document; 
import com.itextpdf.text.PageSize; 
import com.itextpdf.text.pdf.PdfContentByte; 
import com.itextpdf.text.pdf.PdfTemplate; 
import com.itextpdf.text.pdf.PdfWriter; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics2D; 
import java.awt.event.WindowEvent; 
import java.io.FileOutputStream; 
import java.io.OutputStream; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import net.miginfocom.swing.MigLayout; 

public class PanelToPDF { 

    private static JFrame frame= new JFrame(); 
    private static JPanel view= new JPanel(); 
    private static float pageWidth= PageSize.A4.getWidth(); 
    private static float pageHeight= PageSize.A4.getHeight(); 

    public static void main(String[] args) throws Exception { 
     System.out.println("Page width = " + pageWidth + ", height = " + pageHeight); 

     initPane(); 
     createMultipagePDF(); 

     frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING)); 
    } 


    private static void initPane() { 
     view.setLayout(new MigLayout()); 
     view.setBackground(Color.WHITE); 

     for (int i= 1; i <= 160; ++i) { 
      JLabel label= new JLabel("This is a test! " + i); 
      label.setForeground(Color.BLACK); 
      view.add(label, "wrap"); 

      JPanel subPanel= new JPanel(); 
      subPanel.setBackground(Color.RED); 
      view.add(subPanel); 
     } 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(new Dimension(Math.round(pageWidth), Math.round(pageHeight))); 
     frame.add(view); 
     frame.setVisible(true); 
    } 

    private static void createMultipagePDF() throws Exception { 
     // Calculate the number of pages required. Use the preferred size to get 
     // the entire panel height, rather than the panel height within the JFrame 
     int numPages= (int) Math.ceil(view.getPreferredSize().height/pageHeight); // int divided by float 

     // Output to PDF 
     OutputStream os= new FileOutputStream("test.pdf"); 
     Document doc= new Document(); 
     PdfWriter writer= PdfWriter.getInstance(doc, os); 
     doc.open(); 
     PdfContentByte cb= writer.getDirectContent(); 

     // Iterate over pages here 
     for (int currentPage= 0; currentPage < numPages; ++currentPage) { 
      doc.newPage(); // not needed for page 1, needed for >1 

      PdfTemplate template= cb.createTemplate(pageWidth, pageHeight); 
      Graphics2D g2d= new PdfGraphics2D(template, pageWidth, pageHeight * (currentPage + 1)); 
      view.printAll(g2d); 
      g2d.dispose(); 

      cb.addTemplate(template, 0, 0); 
     } 

     doc.close(); 
    } 
İlgili konular