では、前回の「複数ページPDF(1ページ目にグラフ、2ページ目に統計値)」をさらに発展させて、2ページ目の統計値を表形式(PdfPTable)で整形して出力するサンプルを紹介します。
サンプルコード:PdfPTableで統計値を表形式に出力
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.util.*;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
public class ChartPDFWithTable extends JPanel {
private List<Map<Integer, Integer>> datasets;
private List<String> labels;
private String chartTitle = "複数データセットの折れ線グラフ";
public ChartPDFWithTable(List<Map<Integer, Integer>> datasets, List<String> labels) {
this.datasets = datasets;
this.labels = labels;
setPreferredSize(new Dimension(600, 400));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (datasets == null || datasets.isEmpty()) return;
Graphics2D g2 = (Graphics2D) g;
int width = getWidth();
int height = getHeight();
// タイトル
g2.setFont(new Font("SansSerif", Font.BOLD, 16));
FontMetrics fm = g2.getFontMetrics();
int titleWidth = fm.stringWidth(chartTitle);
g2.drawString(chartTitle, (width - titleWidth) / 2, 25);
// 軸
g2.setFont(new Font("SansSerif", Font.PLAIN, 12));
g2.setColor(Color.BLACK);
g2.drawLine(50, height - 50, width - 20, height - 50);
g2.drawLine(50, 30, 50, height - 50);
// 最大値
int maxCount = 0;
for (Map<Integer, Integer> data : datasets) {
if (!data.isEmpty()) {
maxCount = Math.max(maxCount, Collections.max(data.values()));
}
}
// データセット描画
Color[] colors = {Color.RED, Color.BLUE};
int datasetIndex = 0;
for (Map<Integer, Integer> data : datasets) {
g2.setColor(colors[datasetIndex % colors.length]);
List<Integer> keys = new ArrayList<>(data.keySet());
Collections.sort(keys);
int prevX = -1, prevY = -1;
int i = 0;
for (int key : keys) {
int count = data.get(key);
int x = 50 + (i * (width - 100) / (keys.size() - 1));
int y = height - 50 - (int) ((double) count / maxCount * (height - 100));
g2.fillOval(x - 3, y - 3, 6, 6);
if (prevX != -1) g2.drawLine(prevX, prevY, x, y);
prevX = x;
prevY = y;
i++;
}
datasetIndex++;
}
}
public static void main(String[] args) {
// ダミーデータ
Map<Integer, Integer> dataset1 = new LinkedHashMap<>();
dataset1.put(1, 3);
dataset1.put(2, 5);
dataset1.put(3, 2);
dataset1.put(4, 7);
Map<Integer, Integer> dataset2 = new LinkedHashMap<>();
dataset2.put(1, 2);
dataset2.put(2, 4);
dataset2.put(3, 6);
dataset2.put(4, 5);
List<Map<Integer, Integer>> datasets = Arrays.asList(dataset1, dataset2);
List<String> labels = Arrays.asList("データセット1", "データセット2");
ChartPDFWithTable panel = new ChartPDFWithTable(datasets, labels);
try {
// Swingパネルを画像化
BufferedImage image = new BufferedImage(600, 400, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
panel.paint(g2);
g2.dispose();
// PDF作成
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("chart_with_table.pdf"));
document.open();
// 1ページ目:グラフ画像
Image chartImage = Image.getInstance(image, null);
chartImage.scaleToFit(500, 300);
document.add(chartImage);
// 改ページ
document.newPage();
// 2ページ目:統計値を表形式で出力
document.add(new Paragraph("=== 統計値表 ===\n\n"));
PdfPTable table = new PdfPTable(5); // 列数: ラベル, 合計, 平均, 最大, 最小
table.setWidthPercentage(100);
// ヘッダー行
table.addCell("データセット");
table.addCell("合計");
table.addCell("平均");
table.addCell("最大値");
table.addCell("最小値");
// 各データセットの統計値
for (int i = 0; i < datasets.size(); i++) {
Map<Integer, Integer> data = datasets.get(i);
int sum = data.values().stream().mapToInt(Integer::intValue).sum();
double avg = sum / (double) data.size();
int max = Collections.max(data.values());
int min = Collections.min(data.values());
table.addCell(labels.get(i));
table.addCell(String.valueOf(sum));
table.addCell(String.format("%.2f", avg));
table.addCell(String.valueOf(max));
table.addCell(String.valueOf(min));
}
document.add(table);
document.close();
System.out.println("chart_with_table.pdf に保存しました。");
} catch (Exception e) {
e.printStackTrace();
}
// GUI表示(確認用)
JFrame frame = new JFrame("PDF出力用グラフ");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
Java✅ 実行結果
- chart_with_table.pdf が生成されます
- 1ページ目 → グラフ画像
- 2ページ目 → 各データセットの統計値を表形式で表示(合計・平均・最大・最小)
ポイント
PdfPTableを使うと表形式で整った出力が可能- 列数を指定してヘッダー行+データ行を追加
String.format("%.2f", avg)で平均値を小数点2桁に整形
👉 これで「グラフ+統計値表の複数ページPDF出力」が完成しました。

