MFC之word操作

news/2024/9/18 12:39:31/ 标签: mfc, word, c++

word_0">MFC对word操作

背景说明

当对程序的内容进行输出时,比如自定义对象属性描述或者注释(详细设计)生成文档时,如果采用手动输入会比较麻烦,并且当程序变动时,需要再一次修改对应文档,作为程序员做重复性工作非常难受。代码的意义就是为了自动化流程,减少重复性工作。这里以MFC框架下对word进行读写操作为例,其他语言也有类似接口。

word_3">MFC与word接口

前期准备工作可以参考MFC程序创建word,创建表格,写入数据。我用的是Office365,编辑器是vs2022。借助模板插入标签的方法来写入(实际上借助标签来定位并插入文字图片)主要是完成了如下工作,

  1. 插入图片及文本
  2. 设定页脚页眉
  3. 插入表格
  4. 设定表格宽度
  5. 设置表格内容和字体
  6. 读取表格内容以及标题

但是暂时没有解决的

  1. 对目录进行更新目录或者域时总是失败
  2. 无法设置表格的标题
  3. 页眉插入图片失败
  4. 页脚设置页面数(比如page 1 of 100)失败,只能显示页面数1,2这种格式

具体使用了接口如下在这里插入图片描述

代码段

需要注意的是,MFC的COM组件操作word的表格或者行数时都是从1开始的,这与我们编写代码从0计算不一样。
头文件

#pragma once
#include "msword/CApplication.h"
#include "msword/CBookmark0.h"
#include "msword/CBookmarks.h"
#include "msword/CCell.h"
#include "msword/CCells.h"
#include "msword/CColumn.h"
#include "msword/CColumns0.h"
#include "msword/CDocument0.h"
#include "msword/CDocuments.h"
#include "msword/CFontWord.h"
#include "msword/CTable0.h"
#include "msword/CTables0.h"
#include "msword/CRange.h"
#include "msword/CSelection.h"
#include "msword/CnlineShape.h"
#include "msword/CHeaderFooter.h"
#include "msword/CHeadersFooters.h"
#include "msword/CPageSetup.h"
#include "msword/CnlineShapes.h"
#include "msword/CShading.h"
#include "msword/CParagraphFormat.h"
#include "msword/CSection.h"
#include "msword/CSections.h"
#include "msword/CPageNumber.h"
#include "msword/CPageNumbers.h"
#include "msword/CParagraph.h"
#include "msword/CParagraphs.h"
#include "msword/CBorder.h"
#include "msword/CBorders.h"
#include "msword/CRows.h"
#include "msword/CRow.h"
#include "msword/CTableOfContents.h"class WordOperation
{
public:CApplication m_wordApp;CDocuments m_docs;CDocument0 m_docx;CBookmarks m_bookmarks;CBookmark0 m_bookmark;CRange m_range;CCell m_cell;CTables0 m_Tables;CTable0 m_Table;CSelection m_sel;CFontWord m_Font;CRows m_Rows;CColumns0 m_Columns;//第一个Section对应的页脚CHeaderFooter m_footer;//第一个Section对应的页眉CHeaderFooter m_Header;/// <summary>/// word中对应的目录/// </summary>CTableOfContents0 m_tableOfContents;
public:WordOperation(CString templateStr);~WordOperation();/// <summary>/// 将文档保存/// </summary>void SaveFile();/// <summary>/// 写入文本/// </summary>/// <param name="Text">要写入的内容</param>void WriteText(CString Text);/// <summary>/// 新建一段内容/// </summary>/// <param name="nCount">新建行数</param>void NewLine(int nCount = 1);/// <summary>/// 向新建段落写入内容/// </summary>/// <param name="Text">需要写入的内容</param>/// <param name="nCount">新建段落行数</param>void WriteTextToNewLine(CString Text, int nCount = 1);/// <summary>/// 将鼠标移到最后一行/// </summary>void EndLine();/// <summary>/// 插入分页符/// </summary>void InsertPageBreak();/// <summary>/// 设置字体样式/// </summary>/// <param name="blod">是否是粗体</param>/// <param name="Italic">是否斜体 默认值:非斜体</param>/// <param name="UnderLine">是否有下划线 默认值:无下划线</param>void SetFont(BOOL blod,BOOL Italic=FALSE,BOOL UnderLine = FALSE);/// <summary>/// 设置字体/// </summary>/// <param name="FontName">字体名称</param>/// <param name="FontSize">字体大小 默认值:9</param>/// <param name="FontColor">设置字体颜色 默认值:0</param>/// <param name="FontBackColor">设置字体背景色 默认值:0</param>void SetFont(CString FontName, int FontSize = 9, long FontColor = 0, long FontBackColor = 0);/// <summary>/// 获取当前表格指定行数和列数单元格文本/// </summary>/// <param name="Row">要获取单元格的行</param>/// <param name="column">要获取单元格的列</param>/// <returns></returns>CString GetCellText(int Row, int column);/// <summary>/// 设置表格宽度/// </summary>/// <param name="Column">表示设置对象Table的第Column列</param>/// <param name="columnWidth">需要设置的列宽数值:columnWidth</param>void SetTableColumnWidth(int Column, float columnWidth);/// <summary>/// 为文档添加目录/// </summary>void AddTableOfContents();/// <summary>/// 设置表格行数的高度/// <param name="Row">表示设置对象Table的第Row行</param>/// <param name="RowHeigh">行高</param>/// </summary>void SetTableRowHeigh(int Row, float RowHeigh);/// <summary>/// 设置表格的对齐方式/// </summary>/// <param name="Alignment">设置对齐的方式 1:居中对齐 2:右对齐 3:左对齐</param>void SetTableAlignment(int Alignment);/// <summary>/// 创建表格/// </summary>/// <param name="Row">表格的行数</param>/// <param name="Column">表格的列数</param>/// <param name="tableName">表格名称</param>void CreateTable(int Row, int Column,CString tableName);/// <summary>/// 将单元格拆分/// </summary>void SplitTable(int RowSource, int ColumnSource, int RowNum, int ColumnNum);/// <summary>/// 合并单元格/// </summary>void MergeTable(int RowSource, int ColumnSource, int RowGoal, int ColumnGoal);/// <summary>/// 设置表格的单元格字体/// </summary>/// <param name="Row">单元格所在的行</param>/// <param name="Column">单元格所在的列</param>/// <param name="FontName">字体名称</param>/// <param name="FontSize">字体大小</param>/// <param name="FontColor">字体颜色</param>/// <param name="FontBackColor">字体背景色</param>void SetTableFont(int Row, int Column, CString FontName, int FontSize, long FontColor = 0, long FontBackColor = 0);/// <summary>/// 将光标移动到标签指定范围/// </summary>/// <param name="bookmarkText">标签名称</param>void SetCurToBookmark(CString bookmarkText);/// <summary>/// 设置表格的单元格内容/// </summary>/// <param name="Row">单元格所在的行</param>/// <param name="Column">单元格所在的列</param>/// <param name="Text">写入单元格内容</param>void WriteCellText(int Row, int Column, CString Text);/// <summary>/// 设置表格背景颜色/// </summary>/// <param name="Row">单元格所在行</param>/// <param name="Column">单元格所在列</param>/// <param name="ShadingColor">背景色</param>void SetTableShading(int Row, int Column, long ShadingColor = 0);/// <summary>/// 保存word/// </summary>/// <param name="FileName">保存路径</param>/// <param name="SaveType">保存类型</param>/// <returns></returns>BOOL SaveAs(CString FileName, int SaveType);/// <summary>/// 插入指定路径的图片/// </summary>/// <param name="fileName">图片所在路径</param>void InsertShapes(CString fileName);/// <summary>/// 插入位图图片/// </summary>/// <param name="pBitmap">位图指针</param>void InsertShapes(CBitmap* pBitmap);/// <summary>/// 设置页眉/// </summary>/// <param name="HeaderText">页眉内容</param>void SetWordPageHeaderContent(CString HeaderText);/// <summary>/// 设置页脚/// </summary>/// <param name="FooterText">页脚内容</param>void SetWordPageFooterContent(CString FooterText);/// <summary>/// 获取指定表格前面的内容/// </summary>/// <param name="index">表格的排序</param>/// <returns></returns>CString GetTableBeforeName(int index);/// <summary>/// 获取当前文档中表格的数量/// </summary>/// <returns>文档中表格的数量</returns>int GetTableCount();/// <summary>/// 获取当前文档中所有表格的行数/// </summary>/// <returns></returns>int GetAllTableRowCount();/// <summary>/// 获取表格中指定行和列的单元格内容/// </summary>/// <param name="row">指定行</param>/// <param name="column">指定列</param>/// <returns>返回指定单元格内容</returns>CString GetTableCellText(int row, int column);/// <summary>/// 获取表格的行数/// </summary>/// <returns></returns>int GetTableColumnsNum();/// <summary>/// 获取表格的列数目/// </summary>/// <returns></returns>int GetTableRowsNum();
};

cpp文件:

#include "stdafx.h"
#include "WordOperation.h"
#include <comutil.h>
void WordOperation::CreateTable(int row, int column, CString tableName)
{CComVariant DefaultBehavior(1), AutoFitBehavior(2);if (!m_Tables.m_lpDispatch){AfxMessageBox("创建表格对象失败");return;}else{m_Tables.Add(m_sel.get_Range(), row, column, &DefaultBehavior, &AutoFitBehavior);m_Table = m_Tables.Item(m_Tables.get_Count());CBorders borders = m_Table.get_Borders();//设置表格边框COleVariant covboderSingleLine((short)1), covboderOutSideLine((short)13);borders.put_InsideLineStyle(1);//设置内部框线为单线条borders.put_OutsideLineStyle(12);//设置外部框线为双线条long TableWidth = m_Table.get_PreferredWidth();m_Rows = m_Table.get_Rows();m_Columns = m_Table.get_Columns();SetTableAlignment(1);/*LPTSTR lpsz = tableName.GetBuffer();m_Table.get_Title();m_Table.put_Title(lpsz);//这里会报错,设置标题会莫名奇妙的失败*///tableName.ReleaseBuffer();//m_Table.put_PreferredWidth(300);}
}
/// <summary>
/// 拆分单元格
/// </summary>
/// <param name="RowSource">需要被拆分单元格的行</param>
/// <param name="ColumnSource">需要被拆分单元格的列</param>
/// <param name="RowNum">拆分的单元格行数</param>
/// <param name="ColumnNum">拆分的单元格列数</param>
void WordOperation::SplitTable(int RowSource, int ColumnSource, int RowNum, int ColumnNum)
{COleVariant RowNumVariant((short)RowNum), ColumnNumVariant((short)ColumnNum);CCell(m_Table.Cell(RowSource, ColumnSource)).Split(RowNumVariant,ColumnNumVariant);
}
/// <summary>
/// 获取当前表格指定行数和列数单元格文本
/// </summary>
/// <param name="Row">要获取单元格的行</param>
/// <param name="column">要获取单元格的列</param>
/// <returns></returns>
CString WordOperation::GetCellText(int Row, int column)
{CCell m_cell = CCell(m_Table.Cell(Row, column)); //如果被合并的单元格无法访问,这里会直接抛出“所要求的集合不存在",并且无法捕获这个异常CRange cellRange = CCell(m_Table.Cell(Row, column)).get_Range();CString Celltext = cellRange.get_Text();int indexR = Celltext.Find("\r");//去除字符串中的\r\nCelltext = Celltext.Left(indexR);Celltext.TrimLeft();Celltext.TrimRight();return Celltext;
}
/// <summary>
/// 合并单元格
/// </summary>
/// <param name="RowSource">发起合并单元格的行</param>
/// <param name="ColumnSource">发起合并单元的列</param>
/// <param name="RowGoal">需要被合并单元格的行</param>
/// <param name="ColumnGoal">需要被合并单元格的列</param>
void WordOperation::MergeTable(int RowSource, int ColumnSource, int RowGoal, int ColumnGoal)
{CCell(m_Table.Cell(RowSource, ColumnSource)).Merge(m_Table.Cell(RowGoal, ColumnGoal));CCell(m_Table.Cell(RowSource, ColumnSource)).put_VerticalAlignment(1);//合并后居中
}
void WordOperation::SetTableFont(int row, int column, CString FontName, int FontSize, long FontColor, long FontBackColor)
{CCell ce = m_Table.Cell(row, column);ce.Select();CFontWord ft = m_sel.get_Font();ft.put_Name(FontName);ft.put_Size(FontSize);ft.put_Color(FontColor);CRange r = m_sel.get_Range();r.put_HighlightColorIndex(FontBackColor);
}
void WordOperation::SetTableColumnWidth(int column, float columnWidth)
{CColumn(m_Columns.Item(column)).put_PreferredWidth(columnWidth);
}
void WordOperation::SetTableAlignment(int Alignment)
{CRange curTableRange = m_Table.get_Range();CParagraphFormat curTableFormat = curTableRange.get_ParagraphFormat();curTableFormat.put_Alignment(Alignment);//CColumn(m_Columns.Item(column)).SetWidth();
}
void WordOperation::SetTableRowHeigh(int row, float RowHeigh)
{CRow(m_Rows.Item(row)).put_Height(RowHeigh);
}
void WordOperation::WriteCellText(int row, int column, CString Text)
{CCell ce = m_Table.Cell(row, column);ce.Select();m_sel.TypeText(Text);
}
void WordOperation::SetTableShading(int Row, int Column, long ShadingColor)
{CCell ce = m_Table.Cell(Row, Column);ce.Select();CShading s = ce.get_Shading();s.put_BackgroundPatternColor(ShadingColor);
}
void WordOperation::SaveFile()
{if (!m_docx.m_lpDispatch){AfxMessageBox("Documents 对象没有建立 保存失败");return;}else{m_docx.Save();return;}
}
void WordOperation::WriteText(CString Text)
{m_sel.TypeText(Text);
}
void WordOperation::NewLine(int nCount)
{if (nCount <= 0){nCount = 0;}else{for (int i = 0; i < nCount; i++){m_sel.TypeParagraph();//新建一段}}
}
void WordOperation::WriteTextToNewLine(CString text, int nCount)
{NewLine(nCount);WriteText(text);
}
void WordOperation::AddTableOfContents()
{}
void WordOperation::SetCurToBookmark(CString bookmarkText)
{m_bookmark = m_bookmarks.Item(&_variant_t(bookmarkText));m_range = m_bookmark.get_Range();long start = m_range.get_Start();long end = m_range.get_End();m_sel.SetRange(start, end);
}
void WordOperation::EndLine()
{m_sel = m_wordApp.get_Selection();m_sel.EndKey(COleVariant((short)6), COleVariant((short)0));
}
void WordOperation::InsertPageBreak()
{m_sel = m_wordApp.get_Selection();m_sel.InsertBreak(COleVariant((long)7));
}
void WordOperation::SetFont(BOOL Bold, BOOL Italic, BOOL underLine)
{if (!m_sel.m_lpDispatch){AfxMessageBox("编辑对象失败,导致字体不能设置");return;}else{m_sel.put_Text("F");m_Font = m_sel.get_Font();//获得字体编辑对象		m_Font.put_Bold(Bold);		m_Font.put_Italic(Italic);m_Font.put_Underline(underLine);m_sel.put_Font(m_Font);}
}
void WordOperation::SetFont(CString FontName, int FontSize, long FontColor, long FontBackColor)
{if (!m_sel.m_lpDispatch){AfxMessageBox("Select 为空,字体设置失败!");return;}m_sel.put_Text("a");m_Font = m_sel.get_Font();m_Font.put_Name(FontName);m_Font.put_Size(FontSize);m_Font.put_Color(FontColor);m_Font.put_ColorIndex(FontBackColor);m_sel.put_Font(m_Font);
}
void WordOperation::InsertShapes(CString imagePath)
{COleVariant vTrue((short)TRUE), vFalse((short)FALSE), vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);CnlineShapes m_iShapes = m_sel.get_InlineShapes();CnlineShape m_ishape = m_iShapes.AddPicture(imagePath,vFalse,vTrue,vOpt);}
void WordOperation::InsertShapes(CBitmap* pBitmap)
{if (OpenClipboard(NULL)){EmptyClipboard();SetClipboardData(CF_BITMAP, pBitmap->m_hObject);CloseClipboard();m_sel.Paste();}}
BOOL WordOperation::SaveAs(CString FileName, int SaveType)
{CComVariant vTrue(TRUE);CComVariant vFalse(FALSE);CComVariant vOpt;CComVariant cFileName(FileName);CComVariant FileFormat(SaveType);COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);COleVariant covFalse((short)FALSE);if (!m_docx.m_lpDispatch){AfxMessageBox("Document 对象没有建立 另存为失败");return FALSE;}else{//保存之前更新一下目录//m_tableOfContents.UpdatePageNumbers(); 这个总是提示参数数目不对,不知道哪里的问题m_docx.SaveAs(COleVariant(FileName),covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional);//m_docx.Close(covFalse, covOptional, covOptional);AfxMessageBox(_T("生成 ") + FileName + _T(" 成功"));}return TRUE;
}
void WordOperation::SetWordPageHeaderContent(CString HeaderText)
{CRange headRange = m_Header.get_Range();headRange.put_Text(HeaderText);
}
void WordOperation::SetWordPageFooterContent(CString FooterText)
{CRange footRangeEcFir = m_footer.get_Range();footRangeEcFir.put_Text(FooterText);CPageNumbers m_pageNumbers = m_footer.get_PageNumbers();COleVariant covAlignCenter((short)1), covAlignInside((short)3), covAlignNumberLeft((short)0), covAlginOutSide((short)4), covAlignRight((short)2), covFalse((short)FALSE);m_pageNumbers.Add(covAlignRight, covFalse);
}
int WordOperation::GetTableRowsNum()
{m_Rows = m_Table.get_Rows();return m_Rows.get_Count();
}
int WordOperation::GetTableColumnsNum()
{m_Columns = m_Table.get_Columns();return m_Columns.get_Count();
}
CString WordOperation::GetTableCellText(int row, int column)
{m_cell = m_Table.Cell(row, column);CRange cellRange = m_cell.get_Range();return cellRange.get_Text();
}
int WordOperation::GetTableCount()
{return m_Tables.get_Count();
}
int WordOperation::GetAllTableRowCount()
{int RowCount = 0;for (int tableIndex = 1; tableIndex < GetTableCount(); tableIndex++){CTable0 tempTable = m_Tables.Item(tableIndex);if (!tempTable.m_lpDispatch){CRows tablesRows = tempTable.get_Rows();RowCount += tablesRows.get_Count();}}return RowCount;
}
/// <summary>
/// 根据当前表格搜索前方标题,一直找到内容为止,这里的内容就认为是表的标题
/// </summary>
/// <param name="index">表格的排序</param>
/// <returns>表格标题</returns>
CString WordOperation::GetTableBeforeName(int index)
{CString tableName = "";m_Table = m_Tables.Item(index);CRange tableRange = m_Table.get_Range();CParagraphs tableParagraphs = tableRange.get_Paragraphs();CParagraph tableFirstPara = tableParagraphs.get_First();int startIndex = 1;while (tableName.IsEmpty() || tableName == "\r" || tableName == "\t\r" || tableName == " \r"){COleVariant covCount((short)startIndex);CParagraph tableBeforePara = tableFirstPara.Previous(covCount);CRange previousTextRange = tableBeforePara.get_Range();tableName = previousTextRange.get_Text();tableName.Trim();startIndex++;}/*int tableStart = tableRange.get_Start();int tableEnd = tableRange.get_End();CParagraphs paragraphs = m_docx.get_Paragraphs();int paragraphCount = paragraphs.get_Count();*//*for (int iPara = 1; iPara < paragraphCount; iPara++){CParagraph para = paragraphs.Item(iPara);CRange para_Range = para.get_Range();int para_RangeStart = para_Range.get_Start();int para_RangeEnd = para_Range.get_End();if (para_RangeStart >= tableStart){break;}CString paraRangeText = para_Range.get_Text();if (paraRangeText != "\r" && paraRangeText != "\t\r" && paraRangeText != " \r"){tableName = paraRangeText;}}*/return tableName;
}
WordOperation::WordOperation(CString templateStr)
{COleVariant covZero((short)0), covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR), covDocxType((short)0), start_line, end_line, dot(templateStr);if (!m_wordApp.CreateDispatch(_T("Word.Application"))){AfxMessageBox(_T("本机没有安装word产品!"));return;}m_wordApp.put_Visible(FALSE);CString wordVersion = m_wordApp.get_Version();m_docs = m_wordApp.get_Documents();if (!m_docs.m_lpDispatch){AfxMessageBox("Documents创建失败!", MB_OK | MB_ICONWARNING);return;}m_docx = m_docs.Add(dot, covOptional, covOptional, covOptional);if (!m_docx.m_lpDispatch){AfxMessageBox("Document获取失败", MB_OK | MB_ICONWARNING);return;}m_bookmarks = m_docx.get_Bookmarks();m_Tables = m_docx.get_Tables();m_sel = m_wordApp.get_Selection();if (!m_sel.m_lpDispatch){AfxMessageBox("Selection获取失败");}CSections m_wordSections = m_docx.get_Sections();CSection m_wordSection = m_wordSections.get_First();CHeadersFooters m_wordSecHeaderFooters = m_wordSection.get_Headers();CHeadersFooters m_wordFooters = m_wordSection.get_Footers();m_footer = m_wordFooters.Item(1);m_Header = m_wordSecHeaderFooters.Item(1);m_tableOfContents = m_docx.get_TablesOfContents();if (!m_tableOfContents.m_lpDispatch){AfxMessageBox("目录获取失败");}else{/*m_tableOfContents.get_Application();long lowLevel = m_tableOfContents.get_LowerHeadingLevel();long uperLevel = m_tableOfContents.get_UpperHeadingLevel();CRange m_tableOfConRange = m_tableOfContents.get_Range();m_sel.SetRange(m_tableOfConRange.get_Start(),m_tableOfConRange.get_End());m_tableOfContents.UpdatePageNumbers(); // 无法定位到具体的目录,这个只能手动更新了*/}//CHeaderFooter m_footObj = m_wordSecHeaderFooters.Item(2);//BOOL m_isFootObjHeader = m_footObj.get_IsHeader();//CRange headRange = m_Header.get_Range();//CRange footRange = m_footObj.get_Range();//CRange footRangeEcFir = m_footer.get_Range();//BOOL m_bisHeader = m_Header.get_IsHeader();//BOOL m_bIsHeader = m_footer.get_IsHeader();/*int index = m_Headfoot.get_Index();LPDISPATCH pageNums = m_Headfoot.get_PageNumbers();LPDISPATCH parent = m_Headfoot.get_Parent();LPDISPATCH tm = m_Headfoot.get_Shapes();*///CString strHeader = headRange.get_Text();//CString strFooter = footRange.get_Text();//CString strFootRange = footRangeEcFir.get_Text();//footRangeEcFir.put_Text("测试页脚部分");/*int curPageNum = m_sel.get_Information(3).bVal;CString curPageStr = "";curPageStr.Format("%d", curPageNum);footRangeEcFir.InsertAfter("Page");*///footRangeEcFir.get_Fields(COleVariant((long)wdFieldFormText))//footRangeEcFir.InsertAfter(curPageStr);//headRange.put_Start(0);/*CRange headLogoRange=headRange.get_ShapeRange();COleVariant vTrue((short)TRUE), vFalse((short)FALSE), vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);CnlineShapes m_iShapes = headRange.get_InlineShapes();int numShapes = m_iShapes.get_Count();CnlineShape shape_Insert = m_iShapes.Item(1);CRange shape_Range = shape_Insert.get_Range();m_sel.SetRange(shape_Range.get_Start(), shape_Range.get_End());CnlineShape m_ishape = m_iShapes.AddPicture(_T("C:\\Users\\yhwan\\Pictures\\logo\\RSIC.png"), vFalse, vTrue, vOpt);m_ishape.put_Width(100);m_ishape.put_Height(36);*///headRange.put_Text("测试页眉");/*headRange.InsertBefore("测试头部前插入");headRange.InsertAfter("测试头部后插");*///footRange.put_Text("页脚测试");
}WordOperation::~WordOperation()
{COleVariant covZero((short)0), covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR), covDocxType((short)0), start_line, end_line;m_docx.Close(covFalse, covOptional, covOptional);//m_docx.Close(covFalse, covOptional, covOptional);m_wordApp.Quit(covOptional, covOptional, covOptional);m_range.ReleaseDispatch();m_Tables.ReleaseDispatch();m_bookmarks.ReleaseDispatch();m_sel.ReleaseDispatch();m_wordApp.ReleaseDispatch();
}

http://www.ppmy.cn/news/1516476.html

相关文章

修复 502 Bad Gateway 错误的 6 种方法

通常&#xff0c;我们在使用网站时可能会遇到一系列错误。有些非常常见&#xff0c;例如 404&#xff0c;有些则不太常见&#xff0c;例如 101。这些被称为 HTTP 状态代码。其中&#xff0c;502 错误是某种服务器错误。那么&#xff0c;让我们先了解一下 Bad Gateway 502 的含义…

EazyDraw for Mac 矢量图绘制设计软件

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功 三、运行测试安装完成&#xff01;&#xff01;&#xff01; 效果 一、下载软件 下载软件…

SpringMvc 以配置类的形式代替xml文件

1、配置类 1.1、创建Mvc 项目之后创建 MyWebApplicationInitializer 类 实现接口 WebApplicationInitializer public class MyWebApplicationInitializer implements WebApplicationInitializer {Overridepublic void onStartup(ServletContext servletContext) throws Serv…

通过Spring Boot创建项目

目录 引言 一、创建新项目 二、通过spring boot创建顾客查询的项目 1.实体类: 2.mapper接口 3.service服务层接口 4.service服务层接口实现类 5.mapper映射文件 三、可能遇到的问题 引言 在通过之前ssm框架的学习后&#xff0c;你是否会感觉ssm的配置过多&#xff0c…

Redis 的 主从复制

目录 1 Redis 主从复制介绍 2 Redis主从复制原理 2.1 主从同步过程 3 Redis实现主从复制 3.1 环境配置 3.2 修改各节点的配置文件 3.2.1 MASTER 3.2.2 SLAVE 3.3.3 重启Redis 3.3 查看是否实现了主从复制 3.3.1 MASTER 3.3.2 SLAVE 3.3.3 Redis 常用操作 3.3.4 数据添加查看…

Yolo环境搭建(深度学习基础环境)

需要安装的东西 CUDAcuDnn魔法 一、CUDA安装(Windows10环境) 第一&#xff1a;下载驱动 第二&#xff1a;查看显卡支持的最高CUDA的版本&#xff0c;以便下载对应的CUDA安装包 第三&#xff1a;确定CUDA版本对应的cuDNN版本&#xff0c;这个其实不用太关注&#xff0c;因为…

【解析几何笔记】9. 向量的内积运算

9. 向量的内积运算 定义&#xff1a;有向量 α , β \pmb{\alpha},\pmb{\beta} α,β&#xff0c; α ⋅ β ∣ α ∣ ∣ β ∣ ⋅ cos ⁡ < α , β > \pmb{\alpha}\cdot\pmb{\beta}|\pmb{\alpha}||\pmb{\beta}|\cdot\cos<\pmb{\alpha},\pmb{\beta}> α⋅β∣α…

Qt编写贪吃蛇小游戏完整项目

文章目录 前言一、Qt环境准备二、编写思路三、编写代码1、开始游戏界面代码1.1、绘制界面1.2、界面基本配置 2、选择难度界面代码3、游戏房间界面制作3.1、界面基础配置3.2、提前配置类中的成员变量3.2.1、QRectF 3.3、检测游戏是否结束的方法3.4、蛇移动的实现3.4.1、蛇向上移…

【赵渝强老师】执行MySQL的冷备份与冷恢复

冷备份是指发生在数据库已经正常关闭的情况下进行的备份。由于此时数据库已经关闭&#xff0c;通过冷备份可以将数据库的关键性文件拷贝到另外存储位置。冷备份因为只是拷贝文件&#xff0c;因此备份的速度非常快。在执行恢复时&#xff0c;只需将文件再拷贝回去就可以很容易恢…

CPU利用率和CPU负载的区别

CPU利用率和负载虽然相关,但确是两个不同的概念。 CPU利用率 CPU利用率表示CPU实际工作时间与总时间的比率,通常以百分比表示。范围是0% 到 100%&#xff0c;CPU利用率的含义是表示CPU在给定时间内实际执行指令的时间比例&#xff0c;举个例子: 70% 的CPU利用率意味着在某个时…

TCP、UDP

端口号: 端口号: 16位数值(unsigned short ) //0~65535 (65536个数) //标示一个进程 TCP和 UDP 的端口号是独立的 端口号: (1) 作用:唯一的标识一个进程 每一个应用程序进程有一个端口号&#xff0c; 通讯时区分数据包属于哪个应…

硬件面试经典 100 题(81~90)题

81、请问下图电路中二极管 D1、D2 有什么作用&#xff1f; 在 Vi 输入电压接近于零时&#xff0c;D1、D2 给三极管 T1、T2 提供偏置电压&#xff0c;使 T1、T2 维持导通&#xff0c;以消除交越失真。 陈氏解释 这道题参见&#xff1a;硬件面试经典 100 题&#xff08;51~70 题…

Vue3 后台管理系统项目 前端部分

这里写目录标题 1 创建Vue3项目1.1 相关链接1.2 Vue Router1.3 Element1.4 scss1.5 mitt1.6 axios1.7 echarts1.8 配置vite.config.js 2 CSS部分2.1 样式穿透2.2 :style &#xff1a;在样式中使用插值语法 3. ElementUI3.1 rules&#xff1a; 数据验证3.2 修改element.style中的…

信号分解|基于北方苍鹰优化变分模态分解的时序信号分解Matlab程序NGO-VMD

信号分解|基于北方苍鹰优化变分模态分解的时序信号分解Matlab程序NGO-VMD 文章目录 一、基本原理二、实验结果三、核心代码四、代码获取五、总结 信号分解|基于北方苍鹰优化变分模态分解的时序信号分解Matlab程序NGO-VMD 一、基本原理 NGO-VMD结合了北方苍鹰优化算法&#xff…

移动端爬虫学习记录

免责声明 本文旨在探讨移动端爬虫技术的应用和挑战&#xff0c;仅供教育和研究用途。请确保在合法合规的框架内使用爬虫技术&#xff0c;遵循相关法律法规和网站的使用条款。作者不对因使用本文内容而产生的任何法律或安全问题承担责任。 1、初识移动端爬虫 学习移动端爬虫的原…

7. Java 中 HashMap 的扩容机制是怎样的?

​​​​​​HashMap 是基于哈希表的数据结构&#xff0c;其容量是动态调整的。当存储的元素数量增加时&#xff0c;为了保持较好的性能&#xff0c;HashMap 需要进行扩容。HashMap 的扩容机制是为了减少哈希碰撞&#xff0c;提高查询效率。 1. 初始容量和负载因子 初始容量&a…

Android 退出app方式(回忆录)

一、点击返回键或者设备back键调用finish private void back(){finish(); }或Overridepublic void onBackPressed() {super.onBackPressed();}二、结束进程 android.os.Process.killProcess(android.os.Process.myPid()); 三、方法二exit结束java虚拟机 System.exit(0); 四…

uniapp中路由的基本使用方法、参数传递方式以及路由拦截与权限控制

一、概述 在uniapp开发中&#xff0c;路由是非常重要的一个方面&#xff0c;它可以实现页面之间的跳转和传递参数。本文将介绍uniapp中路由的使用技巧&#xff0c;并给出具体的代码示例。 二、uniapp路由的基本使用 在uniapp中&#xff0c;路由的基本使用可以通过uni.navigate…

ai变声:视频怎么变音?分享6个语音变声器,视频变声不再难!

想过如何让自己的直播内容更吸引人吗&#xff1f;你是否希望通过变声器来打造独特的声音效果&#xff1f;或者&#xff0c;如何用创意声音提升观众的互动体验呢&#xff1f;随着直播行业的不断发展&#xff0c;每位主播都在努力寻找吸引观众的独特方式&#xff0c;而变声器正是…

【Test 001】Qt 开发基础体系 QMap 类和 QHash 类以及 QVector 类

文章目录 1.QMap 详解1.1 QMap 的介绍1.2 QMap 的具体用法如下1.3 QmultiMap类 2.QHash 详解3. QMap 和 QHash 的对比4. QVector 详解 1.QMap 详解 1.1 QMap 的介绍 &#x1f427;① QMap<key,T>提供一个从类型为Key的键到类型为T的值的映射。通常&#xff0c;QMap存储的…