上传备份

master
王兵 2 weeks ago
parent 956769bbab
commit cb2f87b9fa

@ -0,0 +1,329 @@
package xyz.wbsite.jmacro.util;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* - Builder
* <p>
*
* TableData.create()
* .addHead("姓名", "年龄", "职业")
* .addData("张三", "25", "工程师")
* .addData("李四", "30", "产品经理")
* .writeToFile(new File("table.png"));
*
* @author wangbing
* @version 0.0.1
* @since 1.8
*/
public class TableData {
/**
*
*/
private static final Font DEFAULT_FONT = new Font(null, Font.PLAIN, 14);
/**
*
*/
private final List<String> head = new ArrayList<>();
/**
*
*/
private final List<List<String>> body = new ArrayList<>();
/**
*
*/
private TableData() {
}
/**
* TableData
*
* @return TableData.Builder
*/
public static TableData create() {
return new TableData();
}
/**
*
*
* @param headers
* @return Builder
*/
public TableData addHead(String... headers) {
this.head.addAll(Arrays.asList(headers));
return this;
}
/**
*
*
* @param rowData
* @return Builder
*/
public TableData addData(String... rowData) {
List<String> row = new ArrayList<>(Arrays.asList(rowData));
this.body.add(row);
return this;
}
private String[][] convertToArrays() {
// 验证数据完整性
if (head.isEmpty()) {
throw new IllegalStateException("必须添加表头");
}
int rows = this.body.size() + 1;
int cols = this.head.size();
String[][] data = new String[rows][cols];
// 填充表头
for (int j = 0; j < cols; j++) {
data[0][j] = this.head.get(j);
}
// 填充数据行
for (int i = 0; i < this.body.size(); i++) {
List<String> row = this.body.get(i);
for (int j = 0; j < cols; j++) {
data[i + 1][j] = row.get(j);
}
}
return data;
}
/**
*
*
* @param data
* @return
*/
private int[] calculateColumnWidths(String[][] data) {
int rows = data.length;
int cols = data[0].length;
// 创建临时Graphics2D对象用于测量文本
BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D tempG2D = tempImage.createGraphics();
tempG2D.setFont(DEFAULT_FONT);
FontMetrics metrics = tempG2D.getFontMetrics();
// 计算每列的最大宽度
int[] colWidths = new int[cols];
for (int j = 0; j < cols; j++) {
int maxWidth = 0;
for (int i = 0; i < rows; i++) {
int textWidth = metrics.stringWidth(data[i][j]);
if (textWidth > maxWidth) {
maxWidth = textWidth;
}
}
colWidths[j] = maxWidth + 20; // 添加内边距
}
tempG2D.dispose();
tempImage.flush();
return colWidths;
}
/**
*
*
* @return
*/
private Dimension calculateTableDimension() {
// 将数据转换为二维数组格式
String[][] data = convertToArrays();
int rows = data.length;
// 计算每列的宽度
int[] colWidths = calculateColumnWidths(data);
// 创建临时Graphics2D对象用于测量文本高度
BufferedImage tempImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D tempG2D = tempImage.createGraphics();
tempG2D.setFont(DEFAULT_FONT);
FontMetrics metrics = tempG2D.getFontMetrics();
// 计算每行的高度(基于字体高度) 添加一些内边距
int rowHeight = metrics.getHeight() + 10;
// 计算总宽度和高度
int totalWidth = 0;
for (int width : colWidths) {
totalWidth += width;
}
int totalHeight = rowHeight * rows;
// 确保最小尺寸
totalWidth = Math.max(totalWidth, 100) + 1;
totalHeight = Math.max(totalHeight, 100) + 1;
tempG2D.dispose();
tempImage.flush();
return new Dimension(totalWidth, totalHeight);
}
/**
*
*
* @return
*/
private BufferedImage drawTable() {
// 将数据转换为二维数组格式
String[][] data = convertToArrays();
// 计算自适应的图像尺寸
Dimension dimension = calculateTableDimension();
int width = dimension.width;
int height = dimension.height;
// 创建图像
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
// 设置背景色为白色
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
// 设置画笔颜色(边框和文字)
g2d.setColor(Color.BLACK);
g2d.setFont(DEFAULT_FONT);
// 计算行列数
int rows = data.length;
int cols = data[0].length;
// 计算单元格宽度(按内容比例分配)
int[] colWidths = calculateColumnWidths(data);
int totalPreferredWidth = 0;
for (int widthValue : colWidths) {
totalPreferredWidth += widthValue;
}
// 如果总推荐宽度大于实际宽度,则按比例调整
if (totalPreferredWidth > width) {
for (int j = 0; j < cols; j++) {
colWidths[j] = (int) ((double) colWidths[j] / totalPreferredWidth * width);
}
}
// 计算单元格高度(平均分配)
int cellHeight = height / rows;
// 绘制表格边框和内容
int y = 0;
for (int i = 0; i < rows; i++) {
int x = 0;
for (int j = 0; j < cols; j++) {
int cellWidth = colWidths[j];
// 绘制单元格边框
g2d.drawRect(x, y, cellWidth, cellHeight);
// 绘制单元格内容(居中显示)
String text = data[i][j];
FontMetrics fm = g2d.getFontMetrics();
int textX = x + (cellWidth - fm.stringWidth(text)) / 2;
int textY = y + (cellHeight + fm.getAscent()) / 2 - fm.getDescent();
g2d.drawString(text, textX, textY);
x += cellWidth;
}
y += cellHeight;
}
g2d.dispose();
return image;
}
/**
*
*
* @param file
* @throws IOException
*/
public void writeToFile(File file) throws IOException {
BufferedImage tableImage = drawTable();
ImageIO.write(tableImage, "png", file);
}
/**
*
*
* @throws Exception
*/
public void writeToClipboard() throws Exception {
BufferedImage tableImage = drawTable();
copyImageToClipboard(tableImage);
}
/**
*
*
* @return
* @throws IOException
*/
public byte[] writeToByteArray() throws IOException {
BufferedImage tableImage = drawTable();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(tableImage, "png", baos);
return baos.toByteArray();
}
/**
*
*
* @param image
*/
private static void copyImageToClipboard(BufferedImage image) {
try {
// 将BufferedImage转为ImageIcon剪贴板支持的格式
ImageIcon imageIcon = new ImageIcon(image);
// 创建剪贴板内容
Transferable transferable = new Transferable() {
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{DataFlavor.imageFlavor};
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return DataFlavor.imageFlavor.equals(flavor);
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
if (DataFlavor.imageFlavor.equals(flavor)) {
return imageIcon.getImage();
}
throw new UnsupportedFlavorException(flavor);
}
};
// 获取系统剪贴板并设置内容
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(transferable, null);
} catch (Exception e) {
throw e;
}
}
}
Loading…
Cancel
Save

Powered by TurnKey Linux.