python生成表格图片非常简单,直接用plot方法就可以搞定了。但是Java做这事就麻烦得多,目前ChatGPT给出的方案全部是基于swing类实现的,原理是先构造一个UI窗口来显示你的信息,然后再对窗口截图。如果是API开发人员做这事等于在做前端开发,下面是代码示例。
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
public class generateImage {
public static void tableImage(JSONArray jsonArray, String outputPath) throws IOException {
// 解析JSON数据
Object[][] data = new Object[jsonArray.size()+1][4];
Object[] columnNames = {"比例", "持有者", "金额", "xid"};
data[0] = columnNames;
for (int i = 1; i <= jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i-1);
data[i][0] = jsonObject.getDouble("fundedRatioNum");
data[i][1] = jsonObject.getString("inv");
data[i][2] = jsonObject.getDouble("subConam");
data[i][3] = jsonObject.getString("xid");
}
// 创建JTable
JTable table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setRowHeight(30);
for (int column = 0; column < table.getColumnCount(); column++) {
TableColumn tableColumn = table.getColumnModel().getColumn(column);
int preferredWidth = tableColumn.getMinWidth();
int maxWidth = tableColumn.getMaxWidth();
for (int row = 0; row < table.getRowCount(); row++) {
TableCellRenderer cellRenderer = table.getCellRenderer(row, column);
Component c = table.prepareRenderer(cellRenderer, row, column);
int width = c.getPreferredSize().width + table.getIntercellSpacing().width;
preferredWidth = Math.max(preferredWidth, width);
// We've exceeded the maximum width, no need to check other rows
if (preferredWidth >= maxWidth) {
preferredWidth = maxWidth;
break;
}
}
tableColumn.setPreferredWidth(preferredWidth);
}
JPanel panel = new JPanel();
panel.add(table);
JFrame frame = new JFrame();
frame.add(panel);
frame.pack();
frame.setVisible(true);
BufferedImage image = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
panel.paint(g);
try {
// Write the BufferedImage to a file
ImageIO.write(image, "png", new File("table.png"));
} catch (IOException e) {
System.out.println("fail");
e.printStackTrace();
}
}
}
这段代码直接执行是没问题的,但是如果集成在Spring Boot里面会报一个HeadlessException错误,大概原因是不可以无头模式渲染这些窗口。需要把Spring Boot入口方法改成下面这样,但是这样带来新的问题是这个窗口你不关就会一直显示在那里,但是应该有一些方法在生成图片之后自动关掉的,但是这总归是一件非常扯的事情。
// SpringApplication.run(App.class, args); SpringApplicationBuilder builder = new SpringApplicationBuilder(App.class); builder.headless(false); ConfigurableApplicationContext context = builder.run(args);
最终我还是放弃了用API生成图片的天真想法。
