テキストを .doc/.docx ファイルにフォーマットする方法を何週間も検索しましたが、良い解決策が見つかりませんでした。
だから私の質問は:
テキストを書式設定して .doc/.docx ファイルを出力するには? (太字、中央など)
あなたの質問はフォーマットが不十分ですが、できる限りお手伝いします。
Microsoft には、C++ での Microsoft Office 書式設定の使用に関するサポート ページがあります。かなり大変な手続きのようです。
あなたが懸念しているファイルは次のとおりです。
ワード 2002 | msword.olb
これは、問題に対処しようとするcodeguru リンクです。多少古くなっている可能性があります。それはあなたがすることができます
CreateBlankDocument()
AppendText(CString szText)
GetLine(int nLine)OpenWordFile(CString szFileName)
SaveWordFileAs(CString szFileName)
わかりました : このMicrosoft Word Automation の投稿では、Word 文書を自動化する際のすべての機能について説明しています。テキストの壁が続くことをお詫びします。
#include "stdafx.h"
#include <ole2.h>
//
// AutoWrap() - Automation helper function...
//
HRESULT AutoWrap(int autoType, VARIANT *pvResult, IDispatch *pDisp,
LPOLESTR ptName, int cArgs...)
{
// Begin variable-argument list...
va_list marker;
va_start(marker, cArgs);
if(!pDisp) {
MessageBox(NULL, "NULL IDispatch passed to AutoWrap()",
"Error", 0x10010);
_exit(0);
}
// Variables used...
DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
HRESULT hr;
char buf[200];
char szName[200];
// Convert down to ANSI
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);
// Get DISPID for name passed...
hr = pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT,
&dispID);
if(FAILED(hr)) {
sprintf(buf,
"IDispatch::GetIDsOfNames(\"%s\") failed w/err0x%08lx",
szName, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
_exit(0);
return hr;
}
// Allocate memory for arguments...
VARIANT *pArgs = new VARIANT[cArgs+1];
// Extract arguments...
for(int i=0; i<cArgs; i++) {
pArgs[i] = va_arg(marker, VARIANT);
}
// Build DISPPARAMS
dp.cArgs = cArgs;
dp.rgvarg = pArgs;
// Handle special-case for property-puts!
if(autoType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}
// Make the call!
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType,
&dp, pvResult, NULL, NULL);
if(FAILED(hr)) {
sprintf(buf,
"IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx",
szName, dispID, hr);
MessageBox(NULL, buf, "AutoWrap()", 0x10010);
_exit(0);
return hr;
}
// End variable-argument section...
va_end(marker);
delete [] pArgs;
return hr;
}
int main(int argc, char* argv[])
{
// Initialize COM for this thread...
CoInitialize(NULL);
// Get CLSID for Word.Application...
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"Word.Application", &clsid);
if(FAILED(hr)) {
::MessageBox(NULL, "CLSIDFromProgID() failed", "Error",
0x10010);
return -1;
}
// Start Word and get IDispatch...
IDispatch *pWordApp;
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER,
IID_IDispatch, (void **)&pWordApp);
if(FAILED(hr)) {
::MessageBox(NULL, "Word not registered properly",
"Error", 0x10010);
return -2;
}
// Make Word visible
{
VARIANT x;
x.vt = VT_I4;
x.lVal = 1;
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pWordApp, L"Visible", 1,
x);
}
// Get Documents collection
IDispatch *pDocs;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pWordApp, L"Documents",
0);
pDocs = result.pdispVal;
}
// Call Documents.Open() to open C:\Doc1.doc
IDispatch *pDoc;
{
VARIANT result;
VariantInit(&result);
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"C:\\Doc1.doc");
AutoWrap(DISPATCH_METHOD, &result, pDocs, L"Open", 1, x);
pDoc = result.pdispVal;
SysFreeString(x.bstrVal);
}
// Get BuiltinDocumentProperties collection
IDispatch *pProps;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc,
L"BuiltinDocumentProperties", 0);
pProps = result.pdispVal;
}
// Get "Subject" from BuiltInDocumentProperties.Item("Subject")
IDispatch *pPropSubject;
{
VARIANT result;
VariantInit(&result);
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"Subject");
AutoWrap(DISPATCH_PROPERTYGET, &result, pProps, L"Item", 1, x);
pPropSubject = result.pdispVal;
SysFreeString(x.bstrVal);
}
// Get the Value of the Subject property and display it
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pPropSubject, L"Value",
0);
char buf[512];
wcstombs(buf, result.bstrVal, 512);
::MessageBox(NULL, buf, "Subject", 0x10000);
}
// Set the Value of the Subject DocumentProperty
{
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"This is my subject");
AutoWrap(DISPATCH_PROPERTYPUT, NULL, pPropSubject, L"Value", 1,
x);
::MessageBox(NULL,
"Subject property changed, examine document.",
"Subject", 0x10000);
SysFreeString(x.bstrVal);
}
// Get CustomDocumentProperties collection
IDispatch *pCustomProps;
{
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_PROPERTYGET, &result, pDoc,
L"CustomDocumentProperties", 0);
pCustomProps = result.pdispVal;
}
// Add a new property named "CurrentYear"
{
VARIANT parm1, parm2, parm3, parm4;
parm1.vt = VT_BSTR;
parm1.bstrVal = SysAllocString(L"CurrentYear");
parm2.vt = VT_BOOL;
parm2.boolVal = false;
parm3.vt = VT_I4;
parm3.lVal = 1; //msoPropertyTypeNumber = 1
parm4.vt = VT_I4;
parm4.lVal = 1999;
AutoWrap(DISPATCH_METHOD, NULL, pCustomProps, L"Add", 4, parm4,
parm3, parm2, parm1);
::MessageBox(NULL, "Custom property added, examine document.",
"Custom Property", 0x10000);
SysFreeString(parm1.bstrVal);
}
// Get the custom property "CurrentYear" and delete it
IDispatch *pCustomProp;
{
VARIANT result;
VariantInit(&result);
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = ::SysAllocString(L"CurrentYear");
AutoWrap(DISPATCH_PROPERTYGET, &result, pCustomProps, L"Item",
1, x);
pCustomProp = result.pdispVal;
SysFreeString(x.bstrVal);
AutoWrap(DISPATCH_METHOD, NULL, pCustomProp, L"Delete", 0);
::MessageBox(NULL,
"Custom property removed, examine document.",
"Custom Property", 0x10000);
}
// Close the document without saving changes and quit Word
{
VARIANT x;
x.vt = VT_BOOL;
x.boolVal = false;
AutoWrap(DISPATCH_METHOD, NULL, pDoc, L"Close", 1, x);
AutoWrap(DISPATCH_METHOD, NULL, pWordApp, L"Quit", 0);
}
// Cleanup
pCustomProp->Release();
pCustomProps->Release();
pPropSubject->Release();
pProps->Release();
pDoc->Release();
pDocs->Release();
pWordApp->Release();
// Uninitialize COM for this thread...
CoUninitialize();
return 0;
}
考えられる解決策の 1 つは、libOPC を使用することです。ドキュメントには簡単な例が示されています (それほど単純ではありません)。そのクロスプラットフォーム ソリューション。
最も単純な例の 1 つ
#include <opc/opc.h>
int main( int argc, const char* argv[] )
{
opcInitLibrary();
opcContainer *c=opcContainerOpen(_X("sample.opc"), OPC_OPEN_READ_WRITE, NULL, NULL);
opcPart part1=opcPartCreate(c, _X("part1.xml"), _X("text/plain"), 0);
opcPart part2=opcPartCreate(c, _X("part2.xml"), _X("text/plain"), 0);
opcContainerOutputStream *stream1=opcContainerCreateOutputStream(c, part1);
opcContainerOutputStream *stream2=opcContainerCreateOutputStream(c, part2);
// WRITE to stream1 and stream2 concurrently using
opcContainerWriteOutputStream(stream1, "HELLO", 5);
opcContainerWriteOutputStream(stream2, "HELLO", 5);
opcContainerWriteOutputStream(stream2, " WORLD", 6);
opcContainerWriteOutputStream(stream1, " WORLD", 6);
opcContainerCloseOutputStream(stream1);
opcContainerCloseOutputStream(stream2);
opcContainerClose(c, OPC_CLOSE_NOW);
opcFreeLibrary();
return 0;
}
ファイルの読み取りまたは書き込み.docxを行う場合は、Office Open XML 形式のドキュメントの EMCA-376 標準に精通する必要があります。これらのドキュメントのコレクション (さまざまな版) は、 EMCA Web サイトで見つけることができます。
ライブラリが必要になるか、Word の自動化を行う必要があります。
Word の内部形式は非常に複雑であり、これを直接実行したくはありません。