如何使用jtable标头在pdf上保存jtable [英] How to save a jtable on pdf with a jtable header
问题描述
我能够在pdf上保存一个jtable,但是表没有标题,请帮助我:
I am able to save a jtable on pdf but table comes without a header please help me :
Document document = new Document(PageSize.A4, 50.0f, 50.0f, 10.0f, 50.0f);
PdfWriter writer = PdfWriter.getInstance((Document)document, (OutputStream)new FileOutputStream(this.file + ".pdf"));
document.open();
PdfContentByte cb1 = writer.getDirectContent();
// modules table
PdfTemplate template = cb1.createTemplate(2480.0f, 3500.0f);
Graphics2D g1 = template.createGraphics((float)this.jTable_Modules2.getWidth(), (float)this.jTable_Modules2.getHeight());
// this.jTable_Modules2.getViewport().setBackground(Color.WHITE);
this.jTable_Modules2.print(g1);
g1.dispose();
com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance((PdfTemplate)template);
image.scalePercent(60.0f);
image.setAbsolutePosition(80.0f, 458.0f);
document.add((Element)image);
document.close();
JOptionPane.showMessageDialog(null, "Transcript successfully generated");
推荐答案
As shown in this answer you can create a new JTable
and pass it as the component to the getImageFromComponent(...)
and it's header appart:
java.awt.Image img = getImageFromComponent(table.getTableHeader());
addImageToDocument(img);
img = getImageFromComponent(table);
addImageToDocument(img);
如果您没有将JTable
添加到JScrollPane
,那么您可以发送JScrollPane
,例如:
That in case you don't add the JTable
to a JScrollPane
, if you do, then you send the JScrollPane
, for example:
java.awt.Image img = getImageFromComponent(scrollPane);
addImageToDocument(img);
由您决定如何添加表格...我更喜欢scrollPane
版本:)
It's up to you how you add the table... I prefer the scrollPane
version :)
另一种方法是遍历JTable
的数据并使用PdfPTable
.
Another way would be to iterate through the JTable
's data and use PdfPTable
.
基于此答案,您可以获得以下内容:
Based on this answer you can get something like this:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
public class JTableToPdf {
private JFrame frame;
private JTable table;
private JButton button;
private Document document;
private PdfWriter writer;
private JScrollPane scrollPane;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JTableToPdf().createAndShowGui();
}
});
}
public void openPdf() throws FileNotFoundException, DocumentException {
document = new Document(PageSize.A4, 30, 30, 30, 30);
writer = PdfWriter.getInstance(document, new FileOutputStream("myFile2.pdf"));
document.open();
}
public void closePdf() {
document.close();
}
public void addData(PdfPTable pdfTable) throws DocumentException {
pdfTable.setHeaderRows(1);
PdfPCell cell = new PdfPCell(new Paragraph(table.getColumnName(0)));
cell.setBackgroundColor(new GrayColor(0.7f));
pdfTable.addCell(cell);
cell = new PdfPCell(new Paragraph(table.getColumnName(1)));
cell.setBackgroundColor(new GrayColor(0.7f));
pdfTable.addCell(cell);
cell = new PdfPCell(new Paragraph(table.getColumnName(2)));
cell.setBackgroundColor(new GrayColor(0.7f));
pdfTable.addCell(cell);
for (int i = 0; i < table.getRowCount(); i++) {
for (int j = 0; j < table.getColumnCount(); j++) {
pdfTable.addCell(table.getModel().getValueAt(i, j).toString());
}
}
document.add(pdfTable);
}
public void createAndShowGui() {
frame = new JFrame("PDF creator");
int rows = 100;
int cols = 3;
String data [][] = new String[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
data[i][j] = i + "-" + j;
}
}
table = new JTable(data, new String []{"A", "B", "C"});
table.setBorder(BorderFactory.createLineBorder(Color.RED));
button = new JButton("Create PDF");
scrollPane = new JScrollPane(table);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
PdfPTable pdfTable = new PdfPTable(table.getColumnCount());
openPdf();
addData(pdfTable);
closePdf();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (DocumentException e1) {
e1.printStackTrace();
}
}
});
// frame.add(table.getTableHeader(), BorderLayout.NORTH);
frame.add(scrollPane, BorderLayout.CENTER);
frame.add(button, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
如果您不想在每个页面上重复标题,只需在addData(...)
方法的for
循环之前删除行即可.
If you don't want the header to repeat on every page just remove the lines before the for
loops on addData(...)
method.
第三种方法可能是使用JTable
的printable
方法,但是我在这里没有打印机,我将在稍后处理此示例,因为目前我没有太多时间而且我不确定如何将其与iText集成在一起,所以我必须进行一些搜索...
A third method could be using the JTable
's printable
methods, but I don't own a printer here, I'll work on this sample later, since I don't have much time at the moment and I'm not sure how to integrate that with iText so I must search a little...
PHEW!创建此结果花了我一段时间,但我认为它很好用(尽管您需要在创建PDF后恢复JTable
).
PHEW! It took me a while to create this result, but I think it works nice (though you need to restore the JTable
after creating the PDF).
看看代码注释,告诉我是否有帮助.我将PDFPTable
的使用和图像方法结合起来使用了这种新方法:
Have a look at the code comments and tell me if this helps. I combined the use of the PDFPTable
and the image approach to get to this new approach:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
public class JTable2Pdf {
private JFrame frame;
private JTable table;
private JButton button;
private JScrollPane scrollPane;
private DefaultTableModel model;
private DefaultTableModel restoreModel;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JTable2Pdf().createAndShowGui();
}
});
}
public void restoreTableView() {
table.setModel(restoreModel);
frame.revalidate();
frame.repaint();
}
public void createAndShowGui() {
frame = new JFrame("PDF creator");
int rows = 130;
int cols = 3;
String data[][] = new String[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
data[i][j] = i + "-" + j;
}
}
model = new DefaultTableModel(data, new String[] { "A", "B", "C" });
restoreModel = new DefaultTableModel(data, new String[] { "A", "B", "C" });
table = new JTable(model);
//Just some borders for the table and its header
table.setBorder(BorderFactory.createLineBorder(Color.RED));
table.getTableHeader().setBorder(BorderFactory.createLineBorder(Color.RED));
scrollPane = new JScrollPane(table);
button = new JButton("Create PDF");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
//We create an instance of pdfCreator and pass our JTable as instance
PdfCreator pdfCreator = new PdfCreator(table);
//We open the pdf and say we want to repeat the header for each page
pdfCreator.openPdf(true);
//Then we add the header (if we don't add it first, then the 1st row of the table will be the one repeating over the pages
pdfCreator.addImageToTable(pdfCreator.getImageFromComponent(table.getTableHeader()));
//Then we add the rows to the PDF
pdfCreator.getRowsImage();
//Finally we close the PDF
pdfCreator.closePdf();
//And last we restore the table
restoreTableView();
} catch (DocumentException e1) {
e1.printStackTrace();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
frame.add(scrollPane, BorderLayout.CENTER);
frame.add(button, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class PdfCreator {
private JTable table;
private Document document;
private PdfWriter writer;
private boolean isNewPage;
private PdfPTable pdfTable;
public PdfCreator(JTable table) {
this.table = table;
}
//This method opens the PDF, repeatHeader if true, adds the header to each page, otherwise it only adds it to the 1st one
public void openPdf(boolean repeatHeader) throws FileNotFoundException, DocumentException {
document = new Document(PageSize.A4, 30, 30, 30, 30);
writer = PdfWriter.getInstance(document, new FileOutputStream("myFile.pdf"));
pdfTable = new PdfPTable(1);
if (repeatHeader) {
pdfTable.setHeaderRows(1);
}
pdfTable.getDefaultCell().setBorder(PdfPCell.NO_BORDER);
pdfTable.getDefaultCell().setPadding(0);
document.open();
}
//This method closes the document
public void closePdf() {
document.close();
}
//This method gets the image for each row recursively
//As this method gets the graphics for the table from 0, 0 to the width and length determined, we need to remove the 1st row of the table
//each time we go through it and that's why we need to restore the table model later in the code
public void getRowsImage() throws DocumentException, IOException {
if (table.getRowCount() > 0) {
int width = table.getCellRect(0, 0, true).width + table.getCellRect(0, 1, true).width + table.getCellRect(0, 2, true).width;
int height = table.getCellRect(0, 0, true).height;
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
table.paint(img.getGraphics());
DefaultTableModel dtm = (DefaultTableModel) table.getModel();
System.out.println(table.getRowCount() + " - " + isNewPage);
dtm.removeRow(0);
addImageToTable(img);
getRowsImage();
} else {
document.add(pdfTable);
}
}
//This gets the image for the table header and / or any other components you need to add to the PDF
public java.awt.Image getImageFromComponent(JComponent component) throws DocumentException {
int width = component.getWidth();
int height = component.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
component.paint(image.getGraphics());
return image;
}
//This method add the image to a PDFPTable which will be added later to the document
public void addImageToTable(java.awt.Image img) throws IOException, DocumentException {
Image image = Image.getInstance(writer, img, 1);
image.scalePercent(100);
pdfTable.addCell(image);
System.out.println("printed!");
}
}
这些是输出:
第一页带有边框和重复页眉 第二页带边框和重复页眉
1st page with borders and repeating header 2nd page with borders and repeating header
第二页带有边框且不重复页眉
2nd page with borders and not repeating header
第一页无边框且不重复页眉 第二页无边框且不重复页眉
1st page with no borders and not repeating header 2nd page with no borders and not repeating header
我能够通过移动而不删除行来更改上面的代码,这会产生相同的结果,并且仍然可以正常工作,但是您不再需要restoreTableView()
方法...只需更改getRowsImage()
方法如下:
I was able to change the above code by moving and not removing the rows this produces the same result and it's still working the same, but you no longer need the restoreTableView()
method... Just change the getRowsImage()
method as follows:
public void getRowsImage() throws DocumentException, IOException {
if (movedRows < table.getRowCount()) {
int width = table.getCellRect(0, 0, true).width + table.getCellRect(0, 1, true).width + table.getCellRect(0, 2, true).width;
int height = table.getCellRect(0, 0, true).height;
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
table.paint(img.getGraphics());
DefaultTableModel dtm = (DefaultTableModel) table.getModel();
System.out.println(table.getRowCount() + " - " + isNewPage);
dtm.moveRow(0, 0, table.getRowCount() - 1);
movedRows++;
addImageToTable(img);
getRowsImage();
} else {
document.add(pdfTable);
}
}
并声明变量movedRows = 0
作为PdfCreator
类的类成员:)
And declare a variable movedRows = 0
as a class member for the PdfCreator
class :)
这篇关于如何使用jtable标头在pdf上保存jtable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!