HSSFRichTextString样式未应用于具有默认值的单元格

时间:2017-01-06 12:26:21

标签: java apache-poi

我是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;在图像中。 这就是我所说的

请帮忙。由于它我完全被阻止了。 提前谢谢,

1 个答案:

答案 0 :(得分:1)

不确定你做错了什么。

假设Source.xls是这样的:

enter image description here

这样的代码:

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像这样:

enter image description here

如您所见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();
  }
 }
}