如何获得具有使用Java定义的宽度的多行富文本字段(任何字体,任何字体大小)所需的高度? [英] How to get the needed height of a multi line rich-text field (any font, any font size) having defined width using Java?
问题描述
我有一个X字体(如Arial字体)的字符串,它的宽度定义为Y高度,这样字符串可以分成多行。我需要计算所需的高度,使所需的字符串可以适应它。由于我需要在行的合并单元格中存在丰富的文本字符串(任何字体和高度)的高度,因此无法在Apache POI中自动调整行大小,在这种情况下,自动大小不起作用。 b $ b
JTextPane
来呈现文本。示例代码首先是整个文本的一种字体和字体大小。但是由于 JTextPane
提供了一个 StyledDocument
,所以富文本内容也应该可以处理。 (TODO)。代码注释了为什么需要代码部分。
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel。*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
$ b public class CreateExcelCellWrapTextRenderedHeight {
public static void main(String [] args)throws Exception {
XSSFWorkbook workbook = new XSSFWorkbook();
Font font = workbook.createFont();
font.setFontName(Arial);
font.setFontHeightInPoints((short)19);
CellStyle cellstyle = workbook.createCellStyle();
cellstyle.setWrapText(true);
cellstyle.setFont(font);
Sheet sheet = workbook.createSheet();
sheet.setColumnWidth(3,25 * 256);
行排= sheet.createRow(0);
字符串文本=字符串单元格内容\行为换行.\\\
它有新的行标记,然后是一个长的文本没有新的行标记。\ \\ n跟着短文本部分。\\ \\ \\ \\从阿克塞尔那里得到许多
Cell cell = row.createCell(2);
cell.setCellValue(text);
cell.setCellStyle(cellstyle);
CellRangeAddress cellRangeAddress = new CellRangeAddress(0,0,2,4);
sheet.addMergedRegion(cellRangeAddress);
// __________________________通过渲染文本来计算文本高度
//获取使用的字体
字体usedfont = workbook.getFontAt(cell.getCellStyle()。getFontIndex ));
//获取使用的字体名称
字符串fontname = usedfont.getFontName();
System.out.println(fontname);
//获取使用的字体大小
short fontheight = usedfont.getFontHeightInPoints();
System.out.println(fontheight);
//获取像素的宽度b $ b float colwidth = 0; $ c
for(int c = cellRangeAddress.getFirstColumn(); c< = cellRangeAddress.getLastColumn(); c ++){
colwidth + = sheet.getColumnWidthInPixels(c);
}
System.out.println(colwidth);
//获取屏幕分辨率
int ppi = java.awt.Toolkit.getDefaultToolkit()。getScreenResolution();
System.out.println(ppi);
//创建一个字体 - 改正大小以适合屏幕分辨率
java.awt.Font awtFont = new java.awt.Font(fontname,java.awt.Font。 PLAIN,Math.round(fontheight /(72f / ppi)));
//创建一个JTextPane来渲染文本
javax.swing.JTextPane textpane = new javax.swing.JTextPane();
//设置字体
textpane.setFont(awtFont);
//将JTextPane的尺寸设置为colwidth和最大高度
java.awt.Dimension dimension = new java.awt.Dimension(Math.round(colwidth),Integer.MAX_VALUE);
textpane.setSize(dimension);
// Excels单元格与默认的行距不同JTextPane
javax.swing.text.MutableAttributeSet attributeset = new javax.swing.text.SimpleAttributeSet(textpane.getParagraphAttributes());
javax.swing.text.StyleConstants.setLineSpacing(attributeset,0.1f);
javax.swing.text.StyledDocument document = textpane.getStyledDocument();
document.setParagraphAttributes(0,document.getLength(),attributeset,true);
//插入文本 - TODO:处理富文本
document.insertString(0,text,null);
//将尺寸调整为首选高度
dimension.setSize(Math.round(colwidth),textpane.getPreferredSize()。getHeight());
textpane.setPreferredSize(dimension);
double textwidthpx = dimension.getWidth();
System.out.println(textwidthpx);
double textheightpx = dimension.getHeight();
System.out.println(textheightpx);
// textheightpx以像素为单位,但是我们需要点
float textheight =(float)textheightpx *(72f / ppi);
System.out.println(textheight);
// __________________________
row.setHeightInPoints(textheight);
workbook.write(new FileOutputStream(CreateExcelCellWrapTextRenderedHeight.xlsx));
workbook.close();
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
TextPaneDemo(textpane).setVisible(true);
}
});
$ b static class TextPaneDemo extends javax.swing.JFrame {
TextPaneDemo(javax.swing.JTextPane textpane){
super ( TextPaneDemo);
this.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
this.getContentPane()。add(textpane,java.awt.BorderLayout.CENTER);
this.pack();
code
$ b < p JTextPane
内容几乎与 Excel中的内容完全一样。因此,身高将基本准确。
使用多种字体和字体大小的测试结果也并不差。
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel。*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
$ b $ public class CreateExcelCellWrapTextRenderedHeightTest {
static float getPreferredHeight(Cell cell,String text,CellRangeAddress cellrangeaddress)throws Exception {
//获取用过的字体
Font usedfont = cell.getSheet()。getWorkbook()。getFontAt(cell.getCellStyle()。getFontIndex());
//获取使用的字体名称
字符串fontname = usedfont.getFontName();
//获取使用的字体大小
short fontheight = usedfont.getFontHeightInPoints();
//获取像素的宽度b $ b float colwidth = 0;
for(int c = cellrangeaddress.getFirstColumn(); c< = cellrangeaddress.getLastColumn(); c ++){
colwidth + = cell.getSheet()。getColumnWidthInPixels(c);
}
//获得屏幕分辨率
int ppi = java.awt.Toolkit.getDefaultToolkit()。getScreenResolution();
//创建一个字体 - 改正大小以适合屏幕分辨率
java.awt.Font awtFont = new java.awt.Font(fontname,java.awt.Font。 PLAIN,Math.round(fontheight /(72f / ppi)));
//创建一个JTextPane来渲染文本
javax.swing.JTextPane textpane = new javax.swing.JTextPane();
//设置字体
textpane.setFont(awtFont);
//将JTextPane的尺寸设置为colwidth和最大高度
java.awt.Dimension dimension = new java.awt.Dimension(Math.round(colwidth),Integer.MAX_VALUE);
textpane.setSize(dimension);
// Excels单元格与默认的行距不同JTextPane
javax.swing.text.MutableAttributeSet attributeset = new javax.swing.text.SimpleAttributeSet(textpane.getParagraphAttributes());
javax.swing.text.StyleConstants.setLineSpacing(attributeset,0.1f);
javax.swing.text.StyledDocument document = textpane.getStyledDocument();
document.setParagraphAttributes(0,document.getLength(),attributeset,true);
//插入文本
document.insertString(0,text,null);
//将尺寸调整为首选高度
dimension.setSize(Math.round(colwidth),textpane.getPreferredSize()。getHeight());
textpane.setPreferredSize(dimension);
double textheightpx = dimension.getHeight();
// textheightpx以像素为单位,但是我们需要点
float textheight =(float)textheightpx *(72f / ppi);
return textheight;
public static void main(String [] args)throws Exception {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
sheet.setColumnWidth(3,30 * 256);
字符串文本=字符串单元格内容\行为换行.\\\
它有新的行标记,然后是一个长的文本没有新的行标记。\ \\ n跟着短文本部分。\\ \\ \\ \\从阿克塞尔那里得到许多
String [] fontnames = new String [] {Arial,Times New Roman,Courier New,Arial Black};
for(int r = 0; r <16; r ++){
Font font = workbook.createFont();
font.setFontName(fontnames [(r%4)]);
font.setFontHeightInPoints((short)(r + 6));
CellStyle cellstyle = workbook.createCellStyle();
cellstyle.setWrapText(true);
cellstyle.setFont(font);
行列= sheet.createRow(r);
Cell cell = row.createCell(2);
cell.setCellValue(text);
cell.setCellStyle(cellstyle);
CellRangeAddress cellrangeaddress = new CellRangeAddress(r,r,2,4);
sheet.addMergedRegion(cellrangeaddress);
float textheight = getPreferredHeight(cell,text,cellrangeaddress);
row.setHeightInPoints(textheight);
workbook.write(new FileOutputStream(CreateExcelCellWrapTextRenderedHeightTest.xlsx));
workbook.close();
$ b code $ pre
I am having a string of X Font(like Arial font) having Y height in define value of the width in such a way that string can comes into multiple lines. I need to calculate the required height so that required string can be fit into it. Auto size of row in Apache POI can't be possible as I require height for the rich text string(any font and height) present in merge cell of the row, in this scenario auto size doesn't work.
解决方案 Found a solution using a JTextPane
to render the text.
Sample code is at first the whole text in one font and fontsize. But since JTextPane
provides a StyledDocument
, rich text content should also be possible to handle. (TODO).
The code comments why code parts are needed.
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
public class CreateExcelCellWrapTextRenderedHeight {
public static void main(String[] args) throws Exception {
XSSFWorkbook workbook = new XSSFWorkbook();
Font font = workbook.createFont();
font.setFontName("Arial");
font.setFontHeightInPoints((short)19);
CellStyle cellstyle = workbook.createCellStyle();
cellstyle.setWrapText(true);
cellstyle.setFont(font);
Sheet sheet = workbook.createSheet();
sheet.setColumnWidth(3, 25*256);
Row row = sheet.createRow(0);
String text = "String cell content\nhaving line wrap.\nIt has new line marks and then a long text without new line marks.\nFollowed by short text part.\n\nGreetings from Axel so long";
Cell cell = row.createCell(2);
cell.setCellValue(text);
cell.setCellStyle(cellstyle);
CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, 2, 4);
sheet.addMergedRegion(cellRangeAddress);
//__________________________calculate text height by rendering the text
//get the used font
Font usedfont = workbook.getFontAt(cell.getCellStyle().getFontIndex());
//get the used font name
String fontname = usedfont.getFontName();
System.out.println(fontname);
//get the used font size
short fontheight = usedfont.getFontHeightInPoints();
System.out.println(fontheight);
//get the width of the colunms in pixels
float colwidth = 0;
for (int c = cellRangeAddress.getFirstColumn(); c <= cellRangeAddress.getLastColumn(); c++) {
colwidth += sheet.getColumnWidthInPixels(c);
}
System.out.println(colwidth);
//get screen resolution
int ppi = java.awt.Toolkit.getDefaultToolkit().getScreenResolution();
System.out.println(ppi);
//create a font - correct the size to be appropriate to the screen resolution
java.awt.Font awtFont = new java.awt.Font(fontname, java.awt.Font.PLAIN, Math.round(fontheight/(72f/ppi)));
//create a JTextPane to render the text
javax.swing.JTextPane textpane = new javax.swing.JTextPane();
//set the font
textpane.setFont(awtFont);
//set dimension of the JTextPane to colwidth and maximum height
java.awt.Dimension dimension = new java.awt.Dimension(Math.round(colwidth), Integer.MAX_VALUE);
textpane.setSize(dimension);
//Excels cells have different line spacing than default JTextPane
javax.swing.text.MutableAttributeSet attributeset = new javax.swing.text.SimpleAttributeSet(textpane.getParagraphAttributes());
javax.swing.text.StyleConstants.setLineSpacing(attributeset, 0.1f);
javax.swing.text.StyledDocument document = textpane.getStyledDocument();
document.setParagraphAttributes(0, document.getLength(), attributeset, true);
//insert the text - TODO: handle rich text
document.insertString(0, text, null);
//resize dimension to preferred height
dimension.setSize(Math.round(colwidth), textpane.getPreferredSize().getHeight());
textpane.setPreferredSize(dimension);
double textwidthpx = dimension.getWidth();
System.out.println(textwidthpx);
double textheightpx = dimension.getHeight();
System.out.println(textheightpx);
//textheightpx is in pixel, but we need points
float textheight = (float)textheightpx * (72f/ppi);
System.out.println(textheight);
//__________________________
row.setHeightInPoints(textheight);
workbook.write(new FileOutputStream("CreateExcelCellWrapTextRenderedHeight.xlsx"));
workbook.close();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TextPaneDemo(textpane).setVisible(true);
}
});
}
static class TextPaneDemo extends javax.swing.JFrame {
TextPaneDemo(javax.swing.JTextPane textpane) {
super("TextPaneDemo");
this.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
this.getContentPane().add(textpane, java.awt.BorderLayout.CENTER);
this.pack();
}
}
}
The JTextPane
content is nearly exact as the content in the Excel
cell. So the height will be mostly accurate.
The result of a test using multiple fonts and font sizes is also not so poor.
import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
public class CreateExcelCellWrapTextRenderedHeightTest {
static float getPreferredHeight(Cell cell, String text, CellRangeAddress cellrangeaddress) throws Exception {
//get the used font
Font usedfont = cell.getSheet().getWorkbook().getFontAt(cell.getCellStyle().getFontIndex());
//get the used font name
String fontname = usedfont.getFontName();
//get the used font size
short fontheight = usedfont.getFontHeightInPoints();
//get the width of the colunms in pixels
float colwidth = 0;
for (int c = cellrangeaddress.getFirstColumn(); c <= cellrangeaddress.getLastColumn(); c++) {
colwidth += cell.getSheet().getColumnWidthInPixels(c);
}
//get screen resolution
int ppi = java.awt.Toolkit.getDefaultToolkit().getScreenResolution();
//create a font - correct the size to be appropriate to the screen resolution
java.awt.Font awtFont = new java.awt.Font(fontname, java.awt.Font.PLAIN, Math.round(fontheight/(72f/ppi)));
//create a JTextPane to render the text
javax.swing.JTextPane textpane = new javax.swing.JTextPane();
//set the font
textpane.setFont(awtFont);
//set dimension of the JTextPane to colwidth and maximum height
java.awt.Dimension dimension = new java.awt.Dimension(Math.round(colwidth), Integer.MAX_VALUE);
textpane.setSize(dimension);
//Excels cells have different line spacing than default JTextPane
javax.swing.text.MutableAttributeSet attributeset = new javax.swing.text.SimpleAttributeSet(textpane.getParagraphAttributes());
javax.swing.text.StyleConstants.setLineSpacing(attributeset, 0.1f);
javax.swing.text.StyledDocument document = textpane.getStyledDocument();
document.setParagraphAttributes(0, document.getLength(), attributeset, true);
//insert the text
document.insertString(0, text, null);
//resize dimension to preferred height
dimension.setSize(Math.round(colwidth), textpane.getPreferredSize().getHeight());
textpane.setPreferredSize(dimension);
double textheightpx = dimension.getHeight();
//textheightpx is in pixel, but we need points
float textheight = (float)textheightpx * (72f/ppi);
return textheight;
}
public static void main(String[] args) throws Exception {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
sheet.setColumnWidth(3, 30*256);
String text = "String cell content\nhaving line wrap.\nIt has new line marks and then a long text without new line marks.\nFollowed by short text part.\n\nGreetings from Axel so long";
String[] fontnames = new String[]{"Arial", "Times New Roman", "Courier New", "Arial Black"};
for (int r = 0; r < 16; r++) {
Font font = workbook.createFont();
font.setFontName(fontnames[(r % 4)]);
font.setFontHeightInPoints((short)(r+6));
CellStyle cellstyle = workbook.createCellStyle();
cellstyle.setWrapText(true);
cellstyle.setFont(font);
Row row = sheet.createRow(r);
Cell cell = row.createCell(2);
cell.setCellValue(text);
cell.setCellStyle(cellstyle);
CellRangeAddress cellrangeaddress = new CellRangeAddress(r, r, 2, 4);
sheet.addMergedRegion(cellrangeaddress);
float textheight = getPreferredHeight(cell, text, cellrangeaddress);
row.setHeightInPoints(textheight);
}
workbook.write(new FileOutputStream("CreateExcelCellWrapTextRenderedHeightTest.xlsx"));
workbook.close();
}
}
这篇关于如何获得具有使用Java定义的宽度的多行富文本字段(任何字体,任何字体大小)所需的高度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!