Docx в HTML: неправильный стиль шрифта заголовков при использовании DOCX4J

#java #html #docx #docx4j

#java #HTML #docx #docx4j

Вопрос:

У меня есть файл docx со стилем Heading1 с Calibri Light (все остальные тексты также используют Calibri Light). После преобразования в html все тексты калибруются (правильно), но текст со стилем Heading1 — это Times New Roman, когда я открываю HTML-файл. (Причина: внутри html-файла нет набора шрифтов для стиля Heading1)

Когда я открываю файл docx и проверяю шрифт стиля Heading1, он говорит Calibri Light.

Заголовок 1 основан на «обычном» стиле в docx.

Это обычный стиль в docx:

 <w:style w:type="paragraph"
        w:default="1"
        w:styleId="Normal">
    <w:name w:val="Normal"/>
    <w:qFormat/>
    <w:rsid w:val="003D736F"/>
    <w:pPr>
        <w:spacing w:before="40"
                    w:after="40"
                    w:line="240"
                    w:lineRule="auto"/>
        <w:ind w:left="851"/>
        <w:jc w:val="both"/>
    </w:pPr>
    <w:rPr>
        <w:rFonts w:ascii="Calibri Light"
                    w:eastAsia="SimSun"
                    w:hAnsi="Calibri Light"
                    w:cs="Times New Roman"/>
        <w:szCs w:val="20"/>
        <w:shd w:val="clear"
                w:color="auto"
                w:fill="FFFFFF"/>
        <w:lang w:eastAsia="zh-CN"/>
    </w:rPr>
</w:style> 
 

Я вижу, у нас есть 4 шрифта. Но можем ли мы указать DOCX4J использовать определенный шрифт (например, использовать w: ascii и поместить этот шрифт в стиль Heading1 в html-файле?) Тексты в стиле заголовка1 тоже должны быть калиброванными, это моя цель.

И это стиль Заголовка1:

     <w:style w:type="paragraph"
            w:styleId="Heading1">
        <w:name w:val="heading 1"/>
        <w:basedOn w:val="Normal"/>
        <w:next w:val="Normal"/>
        <w:link w:val="Heading1Char"/>
        <w:qFormat/>
        <w:rsid w:val="00232342"/>
        <w:pPr>
            <w:keepNext/>
            <w:keepLines/>
            <w:numPr>
                <w:numId w:val="4"/>
            </w:numPr>
            <w:spacing w:before="360"
                        w:after="240"/>
            <w:jc w:val="left"/>
            <w:outlineLvl w:val="0"/>
        </w:pPr>
        <w:rPr>
            <w:b/>
            <w:sz w:val="32"/>
        </w:rPr>
    </w:style>
 

Это код, который я использую:

  WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(source));

 HTMLSettings htmlSettings = Docx4J.createHTMLSettings();
 htmlSettings.setWmlPackage(wordMLPackage);
 htmlSettings.setImageDirPath("temp_images");
 htmlSettings.setImageTargetUri("temp_images");
 htmlSettings.setImageIncludeUUID(false);

 boolean nestLists = false;
 if (nestLists) {
     SdtWriter.registerTagHandler("HTML_ELEMENT", new SdtToListSdtTagHandler());
 } else {
     // convert numberings to plain text
     htmlSettings.getFeatures().remove(ConversionFeatures.PP_HTML_COLLECT_LISTS);
 } 

 OutputStream os = new java.io.FileOutputStream(dest);
 Docx4J.toHTML(htmlSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
 

И это 2 стиля в html

 .Normal {display:block;text-align: justify;position: relative; margin-left: 15mm;margin-top: 1mm;margin-bottom: 1mm;line-height: 100%;}

.Heading1 {display:block;text-align: left;page-break-after: avoid;margin-top: 0.25in;margin-bottom: 4mm;font-weight: bold;font-size: 16.0pt;}
 

Редактировать:
Другим приемлемым решением может быть следующее: установите для семейства шрифтов стиль «DocDefaults» в файле html. Возможно ли это?

Комментарии:

1. Не могли бы вы поместить где-нибудь простой образец docx, в котором показана проблема?

2. ДА. В этом примере есть дополнительная проблема: после преобразования мы видим несколько черных строк на титульной странице (я не знаю почему) drive.google.com/file/d/163eq0LOGjFFxAIkiTgCT9qHqfliUMBSg /…

Ответ №1:

Семейство шрифтов обрабатывается с использованием непосредственно применяемого CSS.

Например:

   <li class="Heading1 Normal DocDefaults " style="display: list-item;"><span class="DefaultParagraphFont " style="font-family: 'Calibri Light';">Chapter 2</span></li></ol>
  
  <p class="Normal DocDefaults "><span class="" style="font-family: 'Calibri Light';">This is an example part, chapter 2</span></p></div>
 

Для применения семейства шрифтов шрифт должен либо физически присутствовать на вашем компьютере, либо отображаться на физически присутствующий шрифт (см. Пример ConvertOutHtml docx4j для примера).

Если это не так, свойство семейства шрифтов не будет выдано.

Для большего понимания вы можете включить ведение журнала на уровне отладки для org.docx4j.fonts.Запустите FontSelector. Пример ведения журнала:

 08:54:21.295 [main] DEBUG org.docx4j.fonts.RunFontSelector 1136 - looking for: Calibri Light
08:54:21.295 [main] DEBUG org.docx4j.fonts.RunFontSelector 1144 - Font 'Calibri Light' maps to Calibri Light
 

Комментарии:

1. Моя отладка: ПРЕДУПРЕЖДЕНИЕ 1569 — [nio-8080-exec-4] org.docx4j.fonts. Физические шрифты: перезапись существующей записи карты физических шрифтов: calibri light WARN 1569 — [nio-8080-exec-4] org.docx4j.fonts. Физические шрифты: перезапись существующей записи physicalFontMap: calibri WARN 1569 — [nio-8080-exec-4] org.docx4j.fonts. Mapper: Перезапись существующего сопоставления шрифтов: calibri light WARN 1569 — [nio-8080-exec-4] org.docx4j.fonts. Mapper: перезапись существующего сопоставления шрифтов: калибровка

2. Проблема все еще существует: все калибровано, кроме 2 чисел заголовка 1. (‘1.’ и ‘2.’) Все остальное в порядке (пытался использовать PhysicalFonts.discoverPhysicalFonts(); , но не решил мою проблему)

3. Вам не нужно этого делать. Итак, установлен Calibri на вашем компьютере или нет? Устанавливаете ли вы FontMapper, например: Mapper fontMapper = new IdentityPlusMapper(); wordMLPackage.setFontMapper(fontMapper);

4. Ну, он не был установлен в моем linux. Что я сделал, так это просто скопировал файл TTF calibri в /USR/SHARE/FONTS/TRUETYPE И нет, я не устанавливаю FontMapper. Рекомендуется ли это делать?