Задание части содержимого ячеек жирным шрифтом / курсивом с помощью библиотеки apache-poi 4.0.1 - PullRequest
0 голосов
/ 26 марта 2019

Я хочу установить содержимое значения ячейки с помощью комбинации жирного и курсивного. как "Это Образец содержание ."

Однако это не работает с использованием 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);

Я ожидаю, что «sample» будет жирным, а «content» - курсивом. Тем не менее, подчеркивание работает нормально, и мое слово «образец» подчеркнуто правильно. Подскажите пожалуйста что мне не хватает?

Ответы [ 3 ]

2 голосов
/ 27 марта 2019
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 здесь для теста, извините.Конечно, такие инструменты, как этот Online-Excel-Viewer , не будут работать правильно.Поэтому, пожалуйста, попробуйте мой код и составьте отчет.

0 голосов
/ 30 марта 2019

Проблема использования 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();
 }
}
0 голосов
/ 26 марта 2019

Поскольку код выглядит правдоподобным, просто выполняю полный прогон:

Следующее, что я протестировал с

  • 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();
}

Я предполагаю, что переменная путаница или что-то тривиальное.Может быть, шрифт.

...