.Net Framework RichTextBox类可以执行转换。幸运的是,这个类已经设置了ComVisibleAttribute属性,所以可以在不太困难的情况下从VBA中使用。
我必须创建一个.tlb文件来引用。在
%SYSTEMROOT%\Microsoft.NET\Framework\currentver\
目录中,运行以下命令:
regasm /codebase system.windows.forms.dll
使用以下命令创建 system.windows.forms.tlb 文件。我已经在我的系统上有这个 .tlb 文件,但是我不得不重新创建它,以便能够在 VBA 中成功创建 .Net System.Windows.Forms RichTextBox 对象。
创建新的 .tlb 文件后,在 VBA 中通过工具->引用链接到您的项目中。
我在 Access 中编写了此测试代码,以演示解决方案。
Dim rtfSample As String
rtfSample = "{\rtf1\ansi\deflang1033\ftnbj\uc1 {\fonttbl{\f0 \froman \fcharset0 Times New Roman;}{\f1 \fswiss \fcharset0 Segoe UI;}} {\colortbl ;\red255\green255\blue255 ;} {\stylesheet{\fs22\cf0\cb1 Normal;}{\cs1\cf0\cb1 Default Paragraph Font;}} \paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\headery720\footery720\deftab720\formshade\aendnotes\aftnnrlc\pgbrdrhead\pgbrdrfoot \sectd\pgwsxn12240\pghsxn15840\marglsxn1440\margrsxn1440\margtsxn1440\margbsxn1440\headery720\footery720\sbkpage\pgnstarts1\pgncont\pgndec \plain\plain\f1\fs22\lang1033\f1 hello question stem\plain\f1\fs22\par}"
Dim miracle As System_Windows_Forms.RichTextBox
Set miracle = New System_Windows_Forms.RichTextBox
With miracle
.RTF = rtfSample
RTFExtractPlainText = .TEXT
End With
MsgBox RTFExtractPlainText(rtfSample)
根据结果
我猜测在64位Windows和64位Office中,需要重新创建\Framework64\目录下的.tlb文件。我正在运行64位Win10和32位Office 2013,所以我需要一个32位的.tlb文件。
另一个选择是使用Microsoft Rich Textbox控件(但无法在x64 Office上测试)
Sub rtfToText()
With CreateObject("RICHTEXT.RichtextCtrl") ' or add reference to Microsoft Rich Textbox Control for early binding and With New RichTextLib.RichTextBox
.SelStart = 0 ' needs to be selected
.TextRTF = Join(Application.Transpose(Cells.CurrentRegion.Columns(1)))
[C1] = .Text ' set the destination cell here
' or if you want them in separate cells:
a = Split(.Text, vbNewLine)
Range("C3").Resize(UBound(a) + 1) = Application.Transpose(a)
End With
End Sub
我重新审视这个问题,提供了两种JavaScript解决方案,而不是.NET
。
const parseRTF = require("rtf-parser");
let rtf = `{\\rtf1\\ansi\\deff0\\nouicompat{\\fonttbl{\\f0\\fnil\\fcharset0 Calibri;}{\\f1\\fnil\\fcharset204 Calibri;}{\\f2\\fnil Calibri;}} {\\colortbl ;\\red0\\green0\\blue0;} {\\*\\generator Riched20 10.0.19041}\\viewkind4\\uc1 \\pard\\cf1\\f0\\fs18\\lang1033 WEB1616 \\f1\\lang1071\\'ef\\'eb\\'e0\\'f2\\'e5\\'ed\\'ee \\'f1\\'ee \\'ea\\'e0\\'f0\\'f2\\'e8\\'f7\\'ea\\'e0\\par \\'ca\\'f0\\'e8\\'f1\\'f2\\'e8\\'ed\\'e0 \\'c3\\'ee\\'eb\\'e0\\'e1\\'ee\\'f1\\'ea\\'e0 077640615\\par \\'c2\\'e0\\'f0\\'f8\\'e0\\'e2\\'f1\\'ea\\'e0 6\\'e0\\par 1000 \\'d1\\'ea\\'ee\\'ef\\'bc\\'e5\\f2\\lang1033\\par } `;
function convertRTFtoPlainText(rtf) {
return new Promise((resolve, reject) => {
parseRTF.string(rtf, (err, doc) => {
if (err) {
reject(err);
}
let string = "";
doc.content.forEach((item) => {
if (item.content) {
item.content.forEach((span) => {
string += span.value;
});
} else {
string += item.value;
}
});
resolve(string.trim());
});
});
}
(async () => {
let value = await convertRTFtoPlainText(rtf);
console.log(value);
})();
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
function stringToArrayBuffer(string) {
if (string == null) return;
let buffer = new ArrayBuffer(string.length);
let bufferView = new Uint8Array(buffer);
for (let i = 0; i < string.length; i++) {
bufferView[i] = string.charCodeAt(i);
}
return buffer;
}
// callback = function to run after the DOM has rendered, defined when calling runRtfjs
function runRtfjs(rtf, callback, errorCallback) {
const virtualConsole = new jsdom.VirtualConsole();
virtualConsole.sendTo(console);
let dom = new JSDOM(
`
<script src="./node_modules/rtf.js/dist/RTFJS.bundle.js"></script>
<script>
RTFJS.loggingEnabled(false);
try {
const doc = new RTFJS.Document(rtfFile);
const meta = doc.metadata();
doc
.render()
.then(function(htmlElements) {
const div = document.createElement("div");
div.append(...htmlElements);
// window.done(meta, div.innerHTML);
// window.done(meta, div.innerText);
window.done(meta, div.textContent); // pass the data to the callback
}).catch(error => window.onerror(error))
} catch (error){
window.onerror(error)
}
</script>
`,
{
resources: "usable",
runScripts: "dangerously",
url: "file://" + __dirname + "/",
virtualConsole,
beforeParse(window) {
window.rtfFile = stringToArrayBuffer(rtf);
window.done = function (meta, html) {
callback(meta, html); // call the callback
};
window.onerror = function (error) {
errorCallback(error);
};
},
}
);
}
let rtf = `{\\rtf1\\ansi\\deff0\\nouicompat{\\fonttbl{\\f0\\fnil\\fcharset0 Calibri;}{\\f1\\fnil\\fcharset204 Calibri;}{\\f2\\fnil Calibri;}} {\\colortbl ;\\red0\\green0\\blue0;} {\\*\\generator Riched20 10.0.19041}\\viewkind4\\uc1 \\pard\\cf1\\f0\\fs18\\lang1033 WEB1616 \\f1\\lang1071\\'ef\\'eb\\'e0\\'f2\\'e5\\'ed\\'ee \\'f1\\'ee \\'ea\\'e0\\'f0\\'f2\\'e8\\'f7\\'ea\\'e0\\par \\'ca\\'f0\\'e8\\'f1\\'f2\\'e8\\'ed\\'e0 \\'c3\\'ee\\'eb\\'e0\\'e1\\'ee\\'f1\\'ea\\'e0 077640615\\par \\'c2\\'e0\\'f0\\'f8\\'e0\\'e2\\'f1\\'ea\\'e0 6\\'e0\\par 1000 \\'d1\\'ea\\'ee\\'ef\\'bc\\'e5\\f2\\lang1033\\par } `;
runRtfjs(
rtf,
(meta, html) => {
console.log(html);
},
(error) => console.error(error)
);