基于参考文档,本文做了优化处理。
优化点:
1. 单元格合并,目前测试的行的单元格合并线进行了优化。不用写单个的for循环去优化,列的还未进行测试,只需要传入的数组坐标不赋值即可。
2. 标题、列宽可控,根据传入的数值。
参考文档:
java 代码:
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @description
* @date 2022/4/22
*/
public class PictureCreateByTextUtil {
public final static PictureCreateByTextUtil pictureUtil = new PictureCreateByTextUtil();
private PictureCreateByTextUtil() {
}
public static PictureCreateByTextUtil getInstance() {
return pictureUtil;
}
/**
* 通过传入的数据,进行图片生成。
* @date 2022/4/22
* @param
* @return
*/
public void createImagesByDefineData(double[] colWidthPercent, String firstTitle, String twoTitle, String[][] tableData, String filePath, String fileName) throws Exception{
myGraphicsGenerationDefineData(colWidthPercent, firstTitle, twoTitle, tableData, filePath, fileName);
}
public void myGraphicsGenerationDefineData(double[] colWidthPercent, String firstTitle, String twoTitle, String cellsValue[][], String path, String fileName) throws Exception{
// 字体大小
int fontTitileSize = 15;
// 横线的行数
int totalrow = cellsValue.length + 1;
// 竖线的行数
int totalcol = 0;
if (cellsValue[0] != null) {
totalcol = cellsValue[0].length;
}
// 图片宽度
int imageWidth = 1792;
// 行高
int rowheight = 40;
// 图片高度
int imageHeight = totalrow * rowheight + 200;
// 起始高度
int startHeight = 50;
// 起始宽度
int startWidth = 10;
// 单元格宽度
int colwidth = (int) ((imageWidth - 20) / totalcol);
BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
Graphics graphics = image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, imageWidth, imageHeight);
graphics.setColor(new Color(220, 240, 240));
//画横线
for (int j = 0; j < totalrow; j++) {
graphics.setColor(Color.black);
graphics.drawLine(startWidth,
startHeight + (j + 1) * rowheight,
startWidth + colwidth * totalcol,
startHeight + (j + 1) * rowheight);
}
// 竖线位置坐标
int[] colLineWidth = new int[colWidthPercent.length];
int startWidthInt = startWidth;
for(int i = 1; i < colWidthPercent.length + 1; i++){
startWidthInt += (int)(imageWidth * colWidthPercent[i - 1]);
// 防止超出
if(startWidthInt > imageWidth){
startWidthInt = imageWidth - startWidth;
}
colLineWidth[i-1] = startWidthInt;
}
//画竖线
for (int k = 0; k < colWidthPercent.length; k++) {
graphics.setColor(Color.black);
graphics.drawLine(colLineWidth[k], startHeight + rowheight, colLineWidth[k], startHeight + rowheight * totalrow);
}
graphics.setColor(Color.black);
//设置字体
Font font = new Font("微软雅黑", Font.BOLD, fontTitileSize);
graphics.setFont(font);
//写标题
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String title02 = "生成时间:" + simpleDateFormat.format(new Date());
graphics.drawString(title02, startWidth, startHeight + rowheight - 10);
Font fonttile = new Font("微软雅黑", Font.BOLD, 18);
graphics.setFont(fonttile);
//写标题
graphics.drawString(firstTitle, 850, 25);
//写标题
graphics.drawString(twoTitle, 790, 60);
//写入内容
for (int n = 0; n < cellsValue.length; n++) {
for (int h = 0; h < cellsValue[n].length; h++) {
if(cellsValue[n] == null || cellsValue[n][h] == null){
// 合并单元格(横着的部分)
graphics.setColor(Color.white);
graphics.drawLine(colLineWidth[h] + 1, startHeight + (n + 1) * rowheight, colLineWidth[h == cellsValue[n].length ? h : (h+1)] - 1, startHeight + (n + 1) * rowheight);
continue;
}
font = new Font("微软雅黑", Font.PLAIN, fontTitileSize);
graphics.setFont(font);
graphics.setColor(Color.BLACK);
if (h > 0) {
if (!cellsValue[n][h].equals(cellsValue[n][h - 1])) {
graphics.drawString(cellsValue[n][h], colLineWidth[h] + 35, startHeight + rowheight * (n + 2) - 10);
}
} else {
graphics.drawString(cellsValue[n][h], colLineWidth[h] + 35, startHeight + rowheight * (n + 2) - 10);
}
}
}
// 保存图片
createImage(image, path, fileName);
}
/**
* 将图片保存到指定位置
*
* @param image 缓冲文件类
* @param fileLocation 文件位置
*/
public static void createImage(BufferedImage image, String fileLocation, String fileName) {
try {
File file = new File(fileLocation);
if (!file.exists()) {
file.mkdir();
}
FileOutputStream fos = new FileOutputStream(fileLocation + fileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
ImageIO.write(image, "jpg", fos);
/* JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
encoder.encode(image);*/
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 图片转换为string
*
* @return
*/
public static String fileToByteArray(String filePath) throws Exception {
BASE64Encoder encoder = new sun.misc.BASE64Encoder();
File file = new File(filePath);
BufferedImage bi = ImageIO.read(file);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, "jpg", baos);
byte[] bytes = baos.toByteArray();
return encoder.encodeBuffer(bytes).trim();
}
public static void main(String[] args) {
String firstTitle = "账户交易记录";
String twoTitle = "用户编号:23523532";
String[] tableTile = {"交易类型", "时间(yyyy-mm-dd hh:mm:ss)", "交易金额", "本金余额", "待还利息", "待还罚息", "待还利息+罚息之和"};
double[] colWidthPercent = {0, 0.1, 0.2, 0.14, 0.14, 0.14, 0.14, 0.14};
String[][] tableData2 = new String[4][tableTile.length];
for(int i = 0; i < tableTile.length; i++){
tableData2[0][i] = tableTile[i];
}
tableData2[1][0] = "放款";
tableData2[2][0] = "还款";
tableData2[3][0] = "罚息";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
tableData2[1][1] = simpleDateFormat.format(new Date());
tableData2[1][2] = "30";
tableData2[2][2] = "50";
tableData2[3][2] = "100";
tableData2[1][3] = "1000";
tableData2[1][4] = "200";
tableData2[1][5] = "2";
tableData2[1][6] = "12000";
try {
PictureCreateByTextUtil.getInstance().createImagesByDefineData(colWidthPercent, firstTitle, twoTitle, tableData2, "K:\\数据\\", "test.jpg");
} catch (Exception e) {
e.printStackTrace();
}
}
}
效果: