使用 apache-poi 4.0.1 库将单元格内容的某些部分设置为粗体/斜体



我想用粗体和斜体的组合来设置单元格值的内容。例如"这是示例内容"。

但是,这在使用XSSFRichTextString时不起作用。

我正在使用 apache poi 库版本 4.0.1。我尝试使用XSSFRichTextString使我的内容加粗和斜体组合。我通过在方法cell1Value.append("sample ", fontBold(中传递两个参数来附加字符串;即字符串和字体。

    XSSFRichTextString cell1Value= new XSSFRichTextString("This is ");
    XSSFFont fontBold= wb.createFont();
    fontBold.setBold(true); //set bold
    fontBold.setUnderline(HSSFFont.U_SINGLE);

    XSSFFont fontItalic= wb.createFont();
    fontItalic.setItalic(true); //set italic
    cell1Value.append("sample ",fontBold);
    cell1Value.append("content", fontItalic);
    System.err.println(cell1Value.getCTRst());
    Cell cell1 = row.createCell(0);
    cell1.setCellValue(cell1Value);
我希望"样本"是

粗体的,"内容"是斜体的。但是,下划线工作正常,我的"示例"字下划线正确。请告诉我我错过了什么?

import java.io.FileOutputStream;
import java.io.OutputStream;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class TextBoldItalic {
  public static void main(String[] args) throws Exception {
    XSSFWorkbook wb = new XSSFWorkbook();
    Sheet sheet = wb.createSheet();
    Row row = sheet.createRow(0);
    Cell cell = row.createCell(0);
    XSSFFont fontBold = wb.createFont();
    fontBold.setBold(true);
    XSSFFont fontItalic = wb.createFont();
    fontItalic.setItalic(true);
    XSSFFont fontBoldItalic = wb.createFont();
    fontBoldItalic.setBold(true);
    fontBoldItalic.setItalic(true);
    XSSFRichTextString cellValue = new XSSFRichTextString();
    cellValue.append("This is ", fontBold);
    cellValue.append("sample ", fontItalic);
    cellValue.append("content", fontBoldItalic);
    cell.setCellValue(cellValue);
    OutputStream fileOut = new FileOutputStream("TextBoldItalic.xlsx");
    wb.write(fileOut);
    wb.close();
  }
}

这段代码对我有用,并在 LibreOffice 中给了我这个结果。OpenOffice也很好。没有MS Excel在这里进行测试,抱歉。当然,像这样的工具在线Excel查看器不会做对。所以,请尝试我的代码并制作报告。

由于代码看起来合理,只需执行完整的运行:

以下我已经测试过

  • org.apache.poi/poi/3.16
  • org.apache.poi/poi-ooxml/3.16

成功了。

try (XSSFWorkbook wb = new XSSFWorkbook()) {
    XSSFSheet sheet = wb.createSheet("With Rich Text");
    Row row = sheet.createRow(0);
    Cell cell = row.createCell(0);
    XSSFFont fontPlain = wb.createFont();
    XSSFFont fontBoldItalic = wb.createFont();
    fontBoldItalic.setBoldItalic(true);
    fontBoldItalic.setItalic(true);
    XSSFFont fontItalic = wb.createFont();
    fontItalic.setItalic(true);
    XSSFRichTextString cell1Value= new XSSFRichTextString("This is ");
    cell1Value.applyFont(fontPlain);
    cell1Value.append("sample ", fontBoldItalic);
    cell1Value.append("content", fontItalic);
    cell.setCellValue(cell1Value);
    wb.write(new FileOutputStream(xlsxFile));
} catch (IOException e) {
    e.printStackTrace();
}

我的猜测是变量混淆或琐碎的事情。也许是字体。

使用WPS Spreadsheets的问题在于它们声称与Excel最兼容,但有时它们完全失败。这一次,如果所有布尔字体设置(粗体、斜体、删除线(明确设置为 true,他们会误解它们。

Office Open XML提供了具有val属性的布尔元素。示例:<b val="true"/><b val="false"/><b val="1"/><b val="0"/>。但是对于设置粗体字体,<b/>就足够了。对于不设置粗体字体,只需根本没有b元素就足够了。

Apache poi总是将<b val="true"/>设置为粗体,<b val="false"/>设置为不大胆。但WPS Spreadsheets现在似乎误解了<b val="true"/>.它只期望<b/>

以下代码是用于为 Excel 创建富文本字符串的最兼容代码。它支持Office Open XML (*.xlsx)BIFF (*.xls),并将<Boolean val="true"/>更正为仅<Boolean/>

import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBooleanProperty;
class CreateExcelRichText {
 static RichTextString createRichTextString(Workbook workbook, String[] textParts, Font[] fonts) {
  CreationHelper creationHelper = workbook.getCreationHelper();
  RichTextString richTextString = creationHelper.createRichTextString(String.join("", textParts));
  int start = 0;
  int end = 0;
  for (int tp = 0; tp < textParts.length; tp ++) {
   Font font = null;
   if (tp < fonts.length) font = fonts[tp];
   end += textParts[tp].length();
   if (font != null) richTextString.applyFont(start, end, font);
   start += textParts[tp].length();
  }
  if (richTextString instanceof XSSFRichTextString) {
   //unset val="true" for boolean objects
   XSSFRichTextString xSSFRichTextString = (XSSFRichTextString)richTextString;
   String[] boolenanObjectsToUnset = new String[]{"b", "i", "strike"};
   for (String boolenanObjectToUnset : boolenanObjectsToUnset) {
    XmlObject[] xmlObjects = xSSFRichTextString.getCTRst().selectPath(
    "declare namespace main='http://schemas.openxmlformats.org/spreadsheetml/2006/main' " +
    ".//main:" + boolenanObjectToUnset);
    for (XmlObject xmlObject : xmlObjects) {
     CTBooleanProperty booleanProperty = (CTBooleanProperty)xmlObject;
     if (booleanProperty.getVal()) booleanProperty.unsetVal();
    }
   }   
  }
  return richTextString;
 }
 public static void main(String[] args) throws Exception {
  Workbook workbook = new XSSFWorkbook(); 
  //Workbook workbook = new HSSFWorkbook(); 
  Font font = workbook.createFont();
  Font fontBoldItalic = workbook.createFont();
  fontBoldItalic.setBold(true);
  fontBoldItalic.setItalic(true);
  Font fontItalic = workbook.createFont();
  fontItalic.setItalic(true);
  Font fontStrikeout = workbook.createFont();
  fontStrikeout.setStrikeout(true);
  String[] textParts = new String[]{"This is ", "Sample ", "content. ", "This is crossed out."};
  Font[] fonts = new Font[]{font, fontBoldItalic, fontItalic, fontStrikeout};
  RichTextString richTextString = createRichTextString(workbook, textParts, fonts);
  Sheet sheet = workbook.createSheet();
  sheet.createRow(0).createCell(0).setCellValue(richTextString);
  String fileName = (workbook instanceof XSSFWorkbook)?"Excel.xlsx":"Excel.xls";
  FileOutputStream out = new FileOutputStream(fileName);
  workbook.write(out);
  out.close();
  workbook.close();
 }
}

最新更新