目前我正在使用以下方法将jtable保存为jpeg,当jtable的维度变为2590,126181时,java.lang.OutOfMemoryError:Java堆空间异常发生在" BufferedImage构造函数",当表格的大小很小,图像成功保存。
public BufferedImage saveComponentAsJPEG(JTable table, String filename) {
Dimension size = table.getSize();
BufferedImage myImage =
new BufferedImage(size.width, size.height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = myImage.createGraphics();
table.paint(g2);
return myImage;
}
如何在pdf或jpeg图像中保存更大尺寸的jtable?
答案 0 :(得分:0)
更新信息:
你问如何将JTable分成不同的小图像":
当您浏览下面的代码时,请阅读我的评论,它们有助于解释正在发生的事情,并将帮助您更好地理解如何将JTable / JComponent绘制到许多小图像上。我的代码与您的代码类似,但有两个关键点:
1)我创建了一个小的图像,然后多次使用,而不是创建一个大的BufferedImage,因此留下的内存占用非常小。
2)使用单个图像,我每次都使用Graphics.translate()来绘制JTable的一小部分。
以下代码使用大型JComponents(2590 x 126181)和瓷砖大小200x200进行测试,整个过程不超过60mb的内存:
//width = width of tile in pixels, for minimal memory usage try 200
//height = height of tile in pixels, for minimal memory usage try 200
//saveFileLocation = folder to save image tiles
//component = The JComponent to save as tiles
public static boolean saveComponentTiles(int width, int height, String saveFileLocation, JComponent component)
{
try
{
//Calculate tile sizes
int componentWidth = component.getWidth();
int componentHeight = component.getHeight();
int horizontalTiles = (int) Math.ceil((double)componentWidth / width); //use (double) so Math.ceil works correctly.
int verticalTiles = (int) Math.ceil((double)componentHeight / height); //use (double) so Math.ceil works correctly.
System.out.println("Tiles Required (H, W): "+horizontalTiles+", verticalTiles: "+verticalTiles);
//preset arguments
BufferedImage image;
//Loop through vertical and horizontal tiles
//Draw part of the component to the image
//Save image to file
for (int h = 0; h < verticalTiles; h++)
{
for (int w = 0; w < horizontalTiles; w++)
{
//check tile size, if area to paint is smaller than image then shrink image
int imageHeight = height;
int imageWidth = width;
if (h + 1 == verticalTiles)
{
imageHeight = componentHeight - (h * height);
}
if (w + 1 == horizontalTiles)
{
imageWidth = componentWidth - (w * width);
}
image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
//translate image graphics so that only the correct part of the component is panted to the image
g.translate(-(w * width), -(h * height));
component.paint(g);
//In my example I am saving the image to file, however you could throw your PDF processing code here
//Files are named as "Image.[h].[w]"
//Example: Image 8 down and 2 accross would save as "Image.8.2.png"
ImageIO.write(image, "png", new File(saveFileLocation + "Image." + h +"."+ w + ".png"));
//tidy up
g.dispose();
}
}
return true;
}
catch (IOException ex)
{
return false;
}
}
就这样称呼它:
boolean result = saveComponentTiles(200, 200, saveFileLocation, jTable1);
此外,如果您尚未完成此操作,则只应从different thread调用该方法,因为它会在处理大型组件时挂起您的应用程序。
如果您尚未选择PDF库,我强烈建议您查看iText。
原帖:
您正在寻找的过程非常简单,但可能需要一些工作。
你正在考虑部件的正确轨道,但作为大卫 提到你不应该混淆jTable,而是你需要一个 使用
TiledImage
课程,或自己做一些事情RenderedImage
和Rasters
。这种方法基本上使用HDD空间而不是内存和 然后,您可以在许多较小的零件/瓷砖中创建大图像 完成后,您可以将其全部保存到单个图像文件中。
这个答案也可能有所帮助:https://stackoverflow.com/a/14069551/1270000