我正在编写一个报告应用程序,我必须以报告的形式导出JTable。但是当我尝试直接在PDF上绘制JTable时,它不会显示第一行和列边框。为此,我尝试使用默认颜色网格左上边框。这给了我一个更深的PDF格式。但是,当尝试使用颜色填充任何特定单元格并将其导出为PDF输出时,所有网格线都是不可见的。
SimpleTableDemo.java :
package com.swing.table;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.LineBorder;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
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 com.swing.data.BorderCellRenderer;
public class SimpleTableDemo extends JPanel implements ActionListener {
private boolean DEBUG = false;
private int spacing = 6;
private Map columnSizes = new HashMap();
String[] columnNames = { "First Name", "Last Name", "Sport", "# of Years",
"Vegetarian" };
Object[][] data = {
{
"Kathy",
"Smith",
"SnowboardingXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
new Integer(5), new Boolean(false) },
{ "John", "Doe", "Rowing", new Integer(3), new Boolean(true) },
{ "Sue", "Black", "Knitting", new Integer(2), new Boolean(false) },
{ "Jane", "White", "Speed reading", new Integer(20),
new Boolean(true) },
{ "Joe", "Brown", "Pool", new Integer(10), new Boolean(false) } };
final JTable table = new JTable(data, columnNames);
public SimpleTableDemo() {
super(new GridLayout(0, 1));
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
// table.setFillsViewportHeight(true);
// Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
BorderCellRenderer cellRenderer = new BorderCellRenderer();
cellRenderer.setBorder(new LineBorder(Color.BLACK));
table.setDefaultRenderer(Object.class, cellRenderer);
table.repaint();
// Add the scroll pane to this panel.
add(scrollPane);
JButton button = new JButton("Create Pdf");
button.addActionListener(this);
add(button);
}
public void actionPerformed(ActionEvent e)
{
print();
}
private void print() {
Document document = new Document(PageSize.A4.rotate());
try {
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("D:/jTable.pdf"));
document.open();
PdfContentByte cb = writer.getDirectContent();
cb.saveState();
PdfTemplate pdfTemplate = cb.createTemplate(table.getWidth(), table.getHeight());
Graphics2D g2 = pdfTemplate.createGraphics(table.getWidth(), table.getHeight());
/*g2.setColor(Color.BLACK);
g2.drawRect(x-2, y-2, table.getWidth()+2, table.getHeight()+2);*/
table.print(g2);
cb.addTemplate(pdfTemplate, 20, 20);
g2.dispose();
cb.restoreState();
} catch (Exception e) {
System.err.println(e.getMessage());
}
document.close();
}
/**
Create the GUI and show it. For thread safety, this method should be
invoked from the event-dispatching thread.
*/
private static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("SimpleTableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create and set up the content pane.
SimpleTableDemo newContentPane = new SimpleTableDemo();
newContentPane.setOpaque(true); // content panes must be opaque
frame.setContentPane(newContentPane);
// Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
BorderCellRenderer.java :
package com.swing.data;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
/**
* @version 1.0 03/06/99
*/
public class BorderCellRenderer extends JLabel
implements TableCellRenderer {
protected Border noFocusBorder;
protected Border columnBorder;
protected Font font;
public Font getFont() {
return font;
}
public void setFont(Font font) {
this.font = font;
}
public BorderCellRenderer() {
noFocusBorder = new EmptyBorder(1, 2, 1, 2);
setOpaque(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
setText((value == null) ? "" : value.toString());
Border b;
b = BorderFactory.createCompoundBorder();
// b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(0,0,1,0,table.getGridColor()));
// b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(0,0,0,1,table.getGridColor()));
/* if(row == 0 && column == 0)
{
setBackground(Color.CYAN);
}
else
{
setBackground(Color.WHITE);
}
*/
if(row==0 || column == 0)
{
if(row ==0 && column==0)
{
b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(0,1,0,0,table.getGridColor()));
b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(1,0,0,0,table.getGridColor()));
}
if(row == 0)
{
b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(1,0,0,0,table.getGridColor()));
setBackground(Color.CYAN);
}
if(column == 0)
{
b = BorderFactory.createCompoundBorder(b, BorderFactory.createMatteBorder(0,1,0,0,table.getGridColor()));
}
}
else
{
b = table.getBorder();
setBackground(Color.WHITE);
}
setBorder(b);
return this;
}
public void setColumnBorder(Border border) {
columnBorder = border;
}
public Border getColumnBorder() {
return columnBorder;
}
}
请尝试使用上面的代码,并帮助我获得带网格线和填充单元格颜色的一对一PDF输出。
更新1: - 我修改了actionPerformed()方法的代码,如下所示: -
public void actionPerformed(ActionEvent e)
{
int x = table.getWidth();
int y = table.getHeight();
BufferedImage bi = null;
if(x>0 && y>0)
{
bi = new BufferedImage(x, y, BufferedImage.TYPE_INT_RGB);
if(bi != null)
{
Graphics g = bi.createGraphics();
table.paint(g);
JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
}
}
print();
}
感谢您查看我的代码。我的要求是不显示表头。我不想按预期打印标题。这就是为什么我的第1行顶部边框和第1列遗留下来的原因。为了纠正这个问题,我手动为第一列和第一行添加了一个默认网格边框。这使得顶部边框看起来是深灰色。除此之外,我还必须用细胞填充细胞。当我将它打印到缓冲的图像时看起来不错,但后来在pdf上它从下面的屏幕截图中删除了我的网格线: -
JTable到bufferedImage输出
JTable到pdf输出
抱歉,我再次发布了封闭的帖子。任何改进我的代码的好建议都会非常有用。
答案 0 :(得分:0)
使用iText。第三方库,可帮助您转换为pdf
public class JTable2Pdf extends JFrame {
private JTable table;
public JTable2Pdf() {
getContentPane().setLayout(new BorderLayout());
createTable();
}
private void createTable() {
Object[][] data = {{ "a", "b", "e", 4, false } };
String[] columnNames = { "A", "B", "C", "D", "E" };
table = new JTable(data, columnNames);
JPanel tPanel = new JPanel(new BorderLayout());
tPanel.add(table.getTableHeader(), BorderLayout.NORTH);
tPanel.add(table, BorderLayout.CENTER);
getContentPane().add(tPanel, BorderLayout.CENTER);
}
private void print() {
Document document = new Document(PageSize.A4.rotate());
try {
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("jTable.pdf"));
document.open();
PdfContentByte cb = writer.getDirectContent();
cb.saveState();
Graphics2D g2 = cb.createGraphicsShapes(500, 500);
Shape oldClip = g2.getClip();
g2.clipRect(0, 0, 500, 500);
table.print(g2);
g2.setClip(oldClip);
g2.dispose();
cb.restoreState();
} catch (Exception e) {
System.err.println(e.getMessage());
}
document.close();
}
public static void main(String[] args) {
JTable2Pdf frame = new JTable2Pdf();
frame.pack();
frame.setVisible(true);
frame.print();
}
}