我是POI的新手,但面临着奇怪的问题。感谢任何快速的帮助。
我有模板xls,其中每个单元格的字体设置为Arial(Font -size:6.5)。 在我的应用程序中,我使用上面的默认模板生成新的Excel报告。
Workbook workbook = new HSSFWorkbook(InputStream s);
因此,新的Excel获取了我的模板xls中指定的所有属性(字体样式)。
现在,当我使用HSSFRichTextString写入特定单元格时,不会应用其样式。 在包含文字和文字的单元格中说我希望将文字作为Arial&数字作为终端。例如,SS 123 SS:Arial,123:终点站。 但由于我的单元格具有默认字体样式Arial,单元格中的所有内容都被写为Arial Only。 虽然当我选择&检查123在单元格中将其描绘的字体显示为终端,但离子实际应用的字体仅为Arial。
private static HSSFRichTextString formatNumbersOfCellText(String outputString,Font numberFont, Font strFont){
HSSFRichTextString formattedString = null;
try{
if(null != outputString && !outputString.trim().equalsIgnoreCase("")){
int lstIndexCalculated=0;
int startIndex ;
int endIndex;
String[] splittedArr = outputString.split("\\s");
if(null != splittedArr && splittedArr.length > 0){
formattedString = new HSSFRichTextString(outputString);
for (int i = 0; i < splittedArr.length; i++) {
if(lstIndexCalculated == 0){
startIndex = outputString.indexOf(splittedArr[i]);
}else{
startIndex = outputString.indexOf(splittedArr[i],lstIndexCalculated);
if(lstIndexCalculated < startIndex){
formattedString.applyFont(lstIndexCalculated,startIndex ,numberFont);
}
}
endIndex = startIndex + (splittedArr[i].length());
lstIndexCalculated = endIndex;
if(isNumericField(splittedArr[i])){
formattedString.applyFont(startIndex,endIndex ,numberFont);
}else{
formattedString.applyFont(startIndex,endIndex ,strFont);
}
startIndex = 0;
endIndex = 0;
}
if(lstIndexCalculated != 0){
return formattedString;
}
}
}
}catch(Exception e){
return null;
}
return null;
}
现在,如果我只给一个子字符串格式化,那么它可以正常工作。
RichTextString richString = new HSSFRichTextString( "SS 123 SS" );
richString.applyFont( 0, 3, font1 );
cell.setCellValue( richString );
这种方法很好,但在下面的情况下,多次迭代会产生问题
RichTextString richString = new HSSFRichTextString( "SS 123 SS" );
richString.applyFont( 0, 3, font1 );
richString.applyFont( 3, 6, font2 );
richString.applyFont( 6, 9, font1 );
cell.setCellValue( richString );
Valid style My incorrect xls style
正如您在终端字体的第一个链接(有效样式)中所看到的,字符&#39; 1&#39;中存在未触发。 但是在Arial中,角色#1;&#39;没有任何不足。所以这是预期的行为。 但在我的情况下,如在第二个链接(我的不正确的xls样式),即使213.27由功能区显示为终端字体,它不是。看到角色&#39; 1&#39;在图像中。 这就是我所说的
请帮忙。由于它我完全被阻止了。 提前谢谢,
答案 0 :(得分:1)
不确定你做错了什么。
假设Source.xls
是这样的:
这样的代码:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
class ReadAndWriteRichText {
public static void main(String[] args) {
try {
InputStream inp = new FileInputStream("Source.xls");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
Row row = sheet.getRow(0);
Cell cell = row.getCell(0);
Font font1 = wb.getFontAt(cell.getCellStyle().getFontIndex());
System.out.println(font1);
Font font2 = wb.createFont();
font2.setFontName("Terminal");
font2.setFontHeightInPoints(font1.getFontHeightInPoints());
System.out.println(font2);
RichTextString richString = new HSSFRichTextString( "SS 123 SS" );
//^0 ^3 ^6 ^9
richString.applyFont( 0, 3, font1 );
richString.applyFont( 3, 6, font2 );
richString.applyFont( 6, 9, font1 );
cell.setCellValue( richString );
FileOutputStream fileOut = new FileOutputStream("Target.xls");
wb.write(fileOut);
wb.close();
} catch (Exception ex) {
}
}
}
将导致Target.xls
像这样:
如您所见123是字体Terminal
。
根据您更新的问题,我提供了一个应该按照需要运行的代码:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
class ReadAndWriteRichText {
private static boolean isNumeric(String string) {
try {
double d = Double.parseDouble(string);
} catch(NumberFormatException nfe) {
return false;
}
return true;
}
private static RichTextString formatNumbersOfCellText(String outputString, Font numberFont, Font strFont) {
RichTextString richString = new HSSFRichTextString(outputString);
String[] tokens = outputString.split("\\s"); // splits on a single space, so possibly empty strings are in the array
int start = 0;
int end = 0;
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i];
end = start + token.length();
if (i < tokens.length - 1) {
end = end + 1; // if not the last token, then take one character more than the length because of formatting the split-delimiter-space after the token
}
if (isNumeric(token)) {
richString.applyFont(start, end, numberFont);
} else {
richString.applyFont(start, end, strFont);
}
start = end;
}
return richString;
}
public static void main(String[] args) {
try {
InputStream inp = new FileInputStream("Source.xls");
Workbook wb = WorkbookFactory.create(inp);
Font font1 = wb.createFont();
font1.setFontName("Arial");
font1.setFontHeightInPoints((short)26);
Font font2 = wb.createFont();
font2.setFontName("Terminal");
font2.setFontHeightInPoints((short)26);
Sheet sheet = wb.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
String cellValue = cell.getStringCellValue(); // all cells must be text cells
RichTextString richString = formatNumbersOfCellText(cellValue, font2, font1);
cell.setCellValue(richString);
}
}
FileOutputStream fileOut = new FileOutputStream("Target.xls");
wb.write(fileOut);
wb.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}