将 HTML 字符串转换为 DocX 对象

问题描述 投票:0回答:1

我创建了一个打字稿脚本,它接受 JSON 字符串并将其包含的信息转换为一种海报,即使用 Docx 的 Word 文档。 JSON 的某些部分可能包含一些 html 标签(不是表或 css 类,但它可能是

<br/>, <i>, <p>
等),我希望能够传入字符串并返回其中之一DocX 对象如
Paragraph
TextRun


我找到了 Html-to-Docx 包,但从文档的外观来看,它想要获取整个 html 字符串并返回一个文件,而我希望能够更改并更好地控制进入和显示的内容WordDoc。我也不想将所有代码更改为 OpenXML 等不同的库。

DocX 中是否还有另一个库/我缺少的东西可以实现此目的?或者我是否必须解析自己的字符串以找到
<br/>, <i>, <p>
标签的位置并尝试将它们单独解析为 DocX 对象? 任何帮助将不胜感激,谢谢

javascript typescript ms-word docx doc
1个回答
0
投票

我已经创建了这个基本的 html 标签转换器,它并不适用于所有用例,但如果有人想添加它以包含更多标签支持或改进代码,他们可以,但这适用于我的用例

    const htmlTagMatch =
            content.match(/<\/?[^>]+(>|$)|[^<]+/g) || [];

    const paragraphStack = [];
    let currentParagraph = [];
    let currentBullet = null;
    let pCount = 0;

    let formattingStack = []; 
    htmlTagMatch.forEach((item, index) =>
    {
        if (item.startsWith('<') && item.endsWith('>')) {
            // Handle HTML tags
            var tag = item.toLowerCase();

            if (pCount % 2 == 0 && tag == '<p>') {
                tag = '</p>';
            }
            switch (tag) {
                case '<i>':
                case '<em>':
                    formattingStack.push('italics');
                    break;
                case '<b>':
                case '<strong>':
                    formattingStack.push('bold');
                    break;
                case '<ul>':
                    if (currentParagraph.length > 0) {
                        paragraphStack.push(
                            createParagraph(currentParagraph, currentBullet)
                        );
                    }
                    currentParagraph = [];
                    break;
                case '<li>':
                    if (currentParagraph.length > 0) {
                        paragraphStack.push(
                            createParagraph(currentParagraph, currentBullet)
                        );
                    }
                    currentBullet = { level: 0 };
                    currentParagraph = [];
                    break;
                case '</i>':
                case '</em>':
                case '</b>':
                case '</strong>':
                    formattingStack.pop();
                    break;
                case '</ul>':
                    if (currentParagraph.length > 0) {
                        paragraphStack.push(
                            createParagraph(currentParagraph, currentBullet)
                        );
                    }
                    currentBullet = null;
                    currentParagraph = [];
                    break;
                case '<br/>':
                case '<br>':
                    currentParagraph.push(new TextRun({ break: 1 }));
                    break;
                case '</p>':
                case '<p>':
                    pCount++;
                    if (htmlTagMatch[index + 1] == '<p>' && htmlTagMatch[index] == '</p>') {
                        break;
                    }
                    // Add a line break
                    if (pCount == 1 && currentParagraph.length > 0) {
                        currentParagraph.push(new TextRun({ break: 2 }));
                    }
                    if (pCount != 1) {
                        currentParagraph.push(new TextRun({ break: 2 }));
                    }
                    break;
            }
        } else {
            // Handle plain text
            let textRun = new TextRun({ text: item });
                
            if (formattingStack.includes('italics')) {
                textRun = new TextRun({ text: item, italics: true });
            }
            if (formattingStack.includes('bold')) {
                textRun = new TextRun({ text: item, bold: true });
            }
                
            currentParagraph.push(textRun);
        }
    });

    // Add the last paragraph to the paragraphStack
    if (currentParagraph.length > 0) {
        paragraphStack.push(createParagraph(currentParagraph, currentBullet));
    }

    return paragraphStack;
© www.soinside.com 2019 - 2024. All rights reserved.