微软的官方文档链接 https://msdn.microsoft.com/zh-cn/vba/word-vba/articles/documents-open-method-word
// 代码打印官方帮助文档
// 包含头文件 #include
// 包含lib Qt5AxContainerd.lib、Qt5AxServerd.lib、Qt5AxBased.lib
// 获取 Word 帮助文档;
QAxObject *pWordApplication = new QAxObject("Word.Application", 0);
QString docWord = pWordApplication->generateDocumentation();
QFile outFile("E:/wordLog.html");
outFile.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream ts(&outFile);
ts << docWord << endl;
// 获取 PPT 帮助文档;
QAxObject *pPPTApplication = new QAxObject("PowerPoint.Application", 0);
QString docPPT = pPPTApplication ->generateDocumentation();
QFile outFile("E:/wordLog.html");
outFile.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream ts(&outFile);
ts << docWord << endl;
1. 使用 HTML 格式输出
限制:不支持 .docx 格式的 Word 文档
void LHCCreateOfficeAPDF::UseHTMLToWord()
{
QString docname = "E:/testhtmlword.doc";
QString html = GetHtmlInfoToFile();
QFile outFile(docname);
outFile.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream ts(&outFile);
ts << html << endl;
}
QString LHCCreateOfficeAPDF::GetHtmlInfoToFile()
{
QString imageData = "\"E:/1.png\"";
QDateTime current_date_time = QDateTime::currentDateTime();
QString current_date = current_date_time.toString("yyyy-MM-dd hh:mm:ss ddd");
QString html = "";
html += "";
html += "";
html += QStringLiteral("qt实现生成word文档 ");
html += "";
html += "";
html += "model
";
html += "" + current_date + "
";
html += "测试qt实现生成word文档
";
html += "
";
html += "
word插入图片
";
html += "
";
html += "";
html += "";
html += "编程语言统计 ";
html += " ";
html += "";
html += "2017-01-18---2018-01-18 ";
html += " ";
html += "
";
html += "";
html += "";
html += "C/C++ ";
html += "python ";
html += "java ";
html += "html ";
html += "Qt ";
html += " ";
html += "";
html += "上升 ";
html += "上升 ";
html += "下降 ";
html += "下降 ";
html += "上升 ";
html += " ";
html += "
";
html += "";
html += "";
return html;
}
2. 使用 QAxObject 插入图片
限制:速度较慢
void LHCCreateOfficeAPDF::UseQAxObjectToWord()
{
QString filePN = QFileDialog::getSaveFileName(this, QStringLiteral("Save File"),
QStringLiteral("./未命名"), tr("Word (*.docx *.doc)"));
if (filePN.isEmpty()) return;
// 初始化;
HRESULT result = OleInitialize(0);
if (result != S_OK && result != S_FALSE)
{
qDebug() << QString("Could not initialize OLE (error %x)").arg((unsigned int)result);
}
//新建一个word应用程序;
QAxObject *m_pWord = new QAxObject();
bool bFlag = m_pWord->setControl("word.Application");
if (!bFlag) return;
// 设置 Office 应用不可见;
m_pWord->setProperty("Visible", false);
// 获取所有的工作文档;
QAxObject *m_pWorkDocuments = m_pWord->querySubObject("Documents");
if (!m_pWorkDocuments) return;
// 新建文档;
m_pWorkDocuments->dynamicCall("Add(void)");
// 以模板 sFile (.dot) 为基础创建文档, sFile为空 表示新建文档;
// document->dynamicCall( "Add(QString)" , sFile);
// 获取当前激活的文档;
QAxObject *m_pWorkDocument = m_pWord->querySubObject("ActiveDocument");
if (!m_pWorkDocument) return;
for (int i = 0; i < 5; ++i)
{
QString picNamePath = "E:\1.png";
QAxObject * bookmark_pic = m_pWord->querySubObject("Selection");
if (!bookmark_pic->isNull())
{
//光标跳到最后一行;
bookmark_pic->dynamicCall("EndOf(QVariant&, QVariant&)", 6,0).toInt();
// selection->dynamicCall("EndOf(void)").toInt();//使用"EndOf(void)"也可实现
QAxObject* range = bookmark_pic->querySubObject("Range");
//插入图片;
range->querySubObject("InlineShapes")->dynamicCall("AddPicture(const QString&)", picNamePath);
}
}
// 保存 Word 文档;
m_pWorkDocument->dynamicCall("SaveAs (const QString&)", filePN);
// 删除 析构 操作;
m_pWord->setProperty("DisplayAlerts", true);
m_pWorkDocument->dynamicCall("Close(bool)", true);
m_pWord->dynamicCall("Quit()");
delete m_pWorkDocuments;
delete m_pWord;
OleUninitialize();
}
3. Word 文档 转换为 PDF
void LHCCreateOfficeAPDF::on_pushB_WordToPDF_clicked()
{
// 接口参照网址 https://docs.microsoft.com/zh-CN/office/vba/api/Word.Documents.Open;
// 利用QAxObject实现word转pdf;
QAxObject *pWordApplication = new QAxObject("Word.Application", 0); //获取Word.Application对象;
QAxObject *pWordDocuments = pWordApplication->querySubObject("Documents"); //获取操作窗口对象;
QString doc1 = pWordApplication->generateDocumentation();
QFile outFile("E:/wordLog.html");
outFile.open(QIODevice::WriteOnly | QIODevice::Append);
QTextStream ts(&outFile);
ts << doc1 << endl;
QString fileName = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/11.docx";
QString toFilePath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/11.pdf";
QVariant filename(fileName);
QVariant confirmconversions(false);
QVariant readonly(true);
QVariant addtorecentfiles(false);
QVariant passworddocument("");
QVariant passwordtemplate("");
QVariant revert(false);
// querySubObject 用法;
// 参数传得少的时候可以用下面做法,如果多的话就用另外的重载版本,如下;
// QAxObject* querySubObject(const char *name, QList &vars);
// 参数装到一个list里,然后传参就行了
// 打开;
QAxObject* doc = pWordDocuments->querySubObject("Open(const QVariant&, const QVariant&,const QVariant&, "
"const QVariant&, const QVariant&, "
"const QVariant&,const QVariant&)",
filename,
confirmconversions,
readonly,
addtorecentfiles,
passworddocument,
passwordtemplate,
revert);
if (doc)
{
QVariant OutputFileName(toFilePath);
QVariant ExportFormat(17); //17是pdf;
QVariant OpenAfterExport(false); //保存后是否自动打开;
//转成pdf;
doc->querySubObject("ExportAsFixedFormat(const QVariant&,const QVariant&,const QVariant&)",
OutputFileName,
ExportFormat,
OpenAfterExport);
//关闭;
doc->dynamicCall("Close(boolean)", false);
}
}
CoInitialize(NULL); // 创建com对象
CoUninitialize(); // 析构com对象
1. 播放 PPT
PlayPPT("E:/embedded.pptx");
void LHCCreateOfficeAPDF::PlayPPT(const QString &pptFilePath)
{
CoInitialize(NULL);
QAxObject pp("PowerPoint.Application", nullptr);
auto presentations = pp.querySubObject("Presentations");
auto presentation = presentations->querySubObject("Open(QString)", pptFilePath);
auto slides = presentation->querySubObject("Slides");
auto sliseshowsettings = presentation->querySubObject("SlideShowSettings");
sliseshowsettings->dynamicCall("Run()");
auto slideshowwindow = presentation->querySubObject("SlideShowWindow");
if (slideshowwindow)
{
auto slideshowview = slideshowwindow->querySubObject("View");
int numSlides = slides->property("Count").toInt();
for (int i = 1; i < numSlides; ++i) {
QThread::currentThread()->sleep(3);
slideshowview->dynamicCall("Next()");
}
}
QThread::currentThread()->sleep(3);
pp.dynamicCall("Quit()");
CoUninitialize();
}
2. 使用 模板 向 PPT 中 插入图片
QAxObject *pptObject = new QAxObject("PowerPoint.Application", nullptr);
QAxObject *presentationsObj = pptObject->querySubObject("Presentations");
QAxObject *presentationObj = presentationsObj->querySubObject("Open(QString, Office::MsoTriState,\
Office::MsoTriState, Office::MsoTriState)", "E:\\Self\\Model.potx", 0, 0, 0);
if (!presentationObj) return;
QVariantList params;
params.append(QVariant("E:\\11.png"));
params.append(-1);
params.append(-1);
params.append(100);
params.append(100);
if (QAxObject *slidesbj = presentationObj->querySubObject("Slides(1)"))
{
if (QAxObject *shapesObj = slidesbj->querySubObject("Shapes"))
{
shapesObj->dynamicCall("AddPicture(QString, Office::MsoTriState, \
Office::MsoTriState,Office::Single, Office::Single)", params);
}
}
presentationObj->dynamicCall("SaveAs (QString)", filePN.replace("/", "\\"));
pptObject->setProperty("DisplayAlerts", true);
pptObject->dynamicCall("Close(bool)", true);
pptObject->dynamicCall("Quit()");
delete presentationObj;
delete presentationsObj;
delete pptObject;
3. 不使用 模板 向 PPT 中 插入图片
QString filePN = QFileDialog::getSaveFileName(this, QStringLiteral("Save File"),
QStringLiteral(".\\default"), tr("PPT (*.pptx *.ppt)"));
if (filePN.isEmpty()) return;
QAxObject *pptObject = new QAxObject("PowerPoint.Application", nullptr);
//Create a presentation in this project
QAxObject *presentationsObj = pptObject->querySubObject("Presentations");
// 参数 Office::MsoTriState 是否在可视窗口中显示演示文稿; 0:不显示; 1:显示;
QAxObject *presentationObj = presentationsObj->querySubObject("Add(Office::MsoTriState)", 0);
if (!presentationObj)
{
return;
}
QVariantList params;
params.append(QVariant("E:\\11.png"));
params.append(-1);
params.append(-1);
params.append(100);
params.append(100);
// Create new Slide
if (QAxObject *slidesbj = presentationObj->querySubObject("Slides"))
{
int sCount = slidesbj->property("Count").toInt();
if (QAxObject *slideMaster = presentationObj->querySubObject("SlideMaster"))
{
if (QAxObject *customLayouts = slideMaster->querySubObject("CustomLayouts"))
{
if (QAxObject *customLayout = customLayouts->querySubObject("Item(QVariant)", QVariant(1)))
{
QAxObject *addSlide = slidesbj->querySubObject("AddSlide(int,Office::CustomLayout)", \
1, customLayout->asVariant());
int sCount2 = slidesbj->property("Count").toInt();
if (QAxObject *shapesObj = addSlide->querySubObject("Shapes"))
{
// Add picture
shapesObj->querySubObject("AddPicture(QString, Office::MsoTriState, Office::MsoTriState, \
Office::Single, Office::Single)", params);
shapesObj->querySubObject("AddPicture(QString, Office::MsoTriState, Office::MsoTriState, \
Office::Single, Office::Single)", params);
}
}
}
}
}
presentationObj->querySubObject("SaveAs (QString)", filePN.replace("/", "\\"));
pptObject->setProperty("DisplayAlerts", true);
pptObject->dynamicCall("Close(bool)", true);
pptObject->dynamicCall("Quit()");
delete presentationObj;
delete presentationsObj;
delete pptObject;
4. PPT 转换为 PDF
void MainWindow::openPPT()
{
QFileDialog _dialog;
_dialog.setFileMode(QFileDialog::ExistingFile);
_dialog.setViewMode(QFileDialog::Detail);
_dialog.setOption(QFileDialog::ReadOnly, true);
_dialog.setDirectory(QString("./"));
_dialog.setNameFilter(QString("ppt(*.pptx *.ppt)"));
if (_dialog.exec())
{
QStringList files = _dialog.selectedFiles();
for (auto fileName : files)
{
if (fileName.endsWith(".pptx")||fileName.endsWith(".ppt"))
{
// Open parameter
QAxObject *_powerPointAxObj = new QAxObject("Powerpoint.Application", 0);
if (!_powerPointAxObj) continue;
_powerPointAxObj->dynamicCall("SetVisible(bool)", false);
QAxObject *presentations = _powerPointAxObj->querySubObject("Presentations");
QList paramList;
paramList.push_back(QVariant(fileName));
paramList.push_back(0);
paramList.push_back(0);
paramList.push_back(0);
//FileName Required String. The name of the file to open
//ReadOnly Optional Long. True to open the file with read-only status. If this argument is omitted, the file is opened with read/write status.
//Untitled Optional Long. True to open the file without a title. This is equivalent to creating a copy of the file. If this argument isn't specified, the file name automatically becomes the title of the opened presentation.
//WithWindow Optional Long. True to open the file in a visible window. False to hide the opened presentation. The default value is True.
QAxObject *presentation = presentations->querySubObject("Open(const QString&,int,int,int)",paramList);
if (presentation != nullptr)
{
paramList.clear();
QString application_path = QApplication::applicationDirPath();
application_path.replace("/", "\\");
application_path += "\\ShowFile.pdf";
paramList.push_back(application_path);
paramList.push_back(32);
paramList.push_back(0);
presentation->dynamicCall("SaveAs(const QString&,int,int)", paramList);
presentations->dynamicCall("Close()");
delete presentations;
//this->OpenPdf(application_path);
}
}
}
}
1. 使用 HTML 格式输出;
void LHCCreateOfficeAPDF::UseHTMLToPdf()
{
QPrinter printer_text;
printer_text.setOutputFormat(QPrinter::PdfFormat);
printer_text.setOutputFileName("E:/HTML.pdf");//pdfname为要保存的pdf文件名;
QTextDocument text_document;
QString html = GetHtmlInfoToFile();//自定义的函数,用来生成html代码;[见 生成Word部分]
text_document.setHtml(html);
text_document.print(&printer_text);
QTextBlock it = text_document.end();
}
2. 使用 QPainter 输出;
限制:手动翻页
参数说明:
QPrinter *m_printer(new QPrinter);
QPrinter *m_painter(new QPainter);
int m_Width = 0; // 插入图片的 width;
int m_Height = 0; // 插入图片的 height;
void LHCCreateOfficeAPDF::UseQPrinterToPdf()
{
QString fileName = "E:/QPrinter.pdf";
SetPdfName(fileName);
WriteTextToPdf("ni hao wo shi 001 PDF TXT");
InsertPictureToPdf("E:/1.png");
CreateNewPage();
WriteTextToPdf("ni hao wo shi 002 PDF TXT");
InsertPictureToPdf("E:/1.png");
EndPainterToPdf();
}
void LHCCreateOfficeAPDF::SetPdfName(const QString &fileName)
{
// 重置绘制的位置;
m_pStruct->m_Height = 0;
m_pStruct->m_printer->setPageSize(QPrinter::A4);
m_pStruct->m_printer->setOutputFormat(QPrinter::PdfFormat);
m_pStruct->m_printer->setOutputFileName(fileName);
m_pStruct->m_painter->begin(m_pStruct->m_printer);
}
void LHCCreateOfficeAPDF::WriteTextToPdf(const QString &text)
{
if (m_pStruct->m_printer == NULL) return;
int height = 10;
int width = 300;
m_pStruct->m_painter->drawText(m_pStruct->m_Width, m_pStruct->m_Height, width, height, 0, text);
m_pStruct->m_Height += height + 10;
}
void LHCCreateOfficeAPDF::InsertPictureToPdf(const QString &picFile)
{
if (m_pStruct->m_printer == NULL) return;
QPixmap *pixmap = new QPixmap(picFile);
int width = pixmap->width();
int height = pixmap->height();
m_pStruct->m_painter->drawPixmap(m_pStruct->m_Width, m_pStruct->m_Height, 300 * width / height, 300, *pixmap);
m_pStruct->m_Height += height;
}
bool LHCCreateOfficeAPDF::CreateNewPage()
{
bool isNew = m_pStruct->m_printer->newPage();
// 重置绘制的位置;
m_pStruct->m_Height = 0;
return isNew;
}
void LHCCreateOfficeAPDF::InsertPictureToPdf(const QPixmap pixmap)
{
if (m_pStruct->m_printer == NULL) return;
int width = pixmap.width();
int height = pixmap.height();
m_pStruct->m_painter->drawPixmap(m_pStruct->m_Width, m_pStruct->m_Height, width, height, pixmap);
m_pStruct->m_Height += height + 10;
}
void LHCCreateOfficeAPDF::EndPainterToPdf()
{
m_pStruct->m_painter->end();
}
3. 使用 QPdfWriter 输出
限制:QT5 版本以上 、手动翻页
void LHCCreateOfficeAPDF::UseQPdfWriterToPdf()
{
QString fileName = "E:/QPdfWriter.pdf";
QFile pdfFile(fileName);
pdfFile.open(QIODevice::WriteOnly); // 打开要写入的pdf文件
QPdfWriter* pPdfWriter = new QPdfWriter(&pdfFile); // 创建pdf写入器
pPdfWriter->setPageSize(QPagedPaintDevice::A4); // 设置纸张为A4
pPdfWriter->setResolution(300); // 设置纸张的分辨率为300,因此其像素为3508X2479
int iMargin = 60; // 页边距
pPdfWriter->setPageMargins(QMarginsF(iMargin, iMargin, iMargin, iMargin));
QPainter* pPdfPainter = new QPainter(pPdfWriter); // qt绘制工具
QTextOption option(Qt::AlignHCenter | Qt::AlignVCenter); // 标题,居中
option.setWrapMode(QTextOption::WordWrap);
// 标题上边留白
int iTop = 100;
// 文本宽度2100
int iContentWidth = 2100;
// 标题,22号字
QFont font;
font.setFamily("simhei.ttf");
int fontSize = 22;
font.setPointSize(fontSize);
pPdfPainter->setFont(font); // 为绘制工具设置字体
pPdfPainter->drawText(QRect(0, iTop, iContentWidth, 90), tr("我的标题我骄傲"), option);
// 内容,16号字,左对齐
fontSize = 16;
font.setPointSize(fontSize);
pPdfPainter->setFont(font);
option.setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
iTop += 60;
pPdfPainter->drawText(QRect(0, iTop, iContentWidth, 60), tr("1、目录一"));
iTop += 60;
// 左侧缩进2字符
int iLeft = 120;
pPdfPainter->drawText(QRect(iLeft, iTop, iContentWidth - iLeft, 60), tr("我的目录一的内容。"), option);
iTop += 60;
pPdfPainter->drawText(QRect(0, iTop, iContentWidth, 60), tr("2、目录二"));
iTop += 60;
pPdfPainter->drawText(QRect(iLeft, iTop, iContentWidth - iLeft, 60), tr("我的目录一的内容"), option);
delete pPdfPainter;
delete pPdfWriter;
pdfFile.close();
}