如何获得具有使用Java定义的宽度的多行富文本字段(任何字体,任何字体大小)所需的高度? [英] How to get the needed height of a multi line rich-text field (any font, any font size) having defined width using Java?

查看:565
本文介绍了如何获得具有使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆