qt导出word模板(模块化程序,直接调用保存数据到指定路径)
前言:
qt导出word模块化程序,根据需求不同只需更改一个函数内容,设置表格格式,之后直接调用保存即可,简单好用,快捷方便
环境:
qt5.7(MinGW)
windows
正文:
word.h
#ifndef QWORD_H
#define QWORD_H
#include <QMainWindow>
#include <QString>
#include <QVariant>
#include <QAxObject>
#include <QAxWidget>
#include <QTextCodec>
struct testDataType
{QString user; //使用者QString code; //设备编号QString fenshu;//得分xxx};class QWord : public QObject
{Q_OBJECTpublic:QWord(QObject *parent = 0);~QWord();public:QAxObject* getDocuments(){return m_documents;}QAxObject* getDocument(){return m_document;}QAxObject* getWordApp(){return m_word;}
public:/**************************************************************************//* 文件 操作 *//**************************************************************************/void save(); //保存操作内容void close(); //关闭 退出 析构时候也会自动调用一次void saveAs(); //新建excel另存为bool createNewWord(); //创建一个新的excelvoid openWord(); //打开一个现有的excelbool createNewWord(const QString& filePath ); //创建一个新的excelvoid setTableAutoFitBehavior(int flag); //表格自动拉伸列 0固定 1根据内容调整 2 根据窗口调整void setPageOrientation(int flag); //设置页面0为纵向wdOrientPortrait 1为横向wdOrientLandscapevoid setWordPageView(int flag); //设置页面视图,是web视图wdWebView 6还是页面视图wdPrintView 3 或者阅读视图wdReadingView 7void setFontSize(int fontsize); //设置字体大小void setFontName(QString& fontName); //设置字体 比如 “宋体”void setFontBold(bool flag); //字体加粗void setParagraphAlignment(int flag); //设置选中位置文字居中 0 ,居左 1,居右 2void setColumnWidth(int column, int width); //设置列宽void setCellString(int row, int column, const QString& text);void setCellFontBold(int row, int column, bool isBold); //设置内容粗体 isBold控制是否粗体void setCellFontSize(int row, int column, int size); //设置文字大小void setOptionCheckSpell(bool flags); //设置审阅的拼写检查 true开启检查 false 取消检查QString GetText(); //获取内容void getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn);void setSelectionRange(int start,int end); //"SetRange(1, 9)"第1个字符后开始,到第9个字符结束范围QVariant getCellValue(int row, int column); //获取单元格内容int getTableCount(); //获取word中表格总数QString getStrErrorInfo(){return m_strError;} //获取代码中出现的错误信息可以用QMessageBox::information打印 在cpp不用QMessageBox 是怕你们在线程中调导出报表void deleteSelectColumn(int column); //删除指定的列void moveForEnd(); //移动选定对象到文档末尾void insertCellPic(int row,int column,const QString& picPath); //单元格插入图片void intsertTable(int row,int column); //插入一个几行几列表格void insertMoveDown(); //插入回车void insertText(const QString& text); //插入文字void inserttestdata(testDataType &str);private:QAxObject* m_word;QAxObject* m_documents;QAxObject* m_document;QString m_fileName;QString m_saveName;QString m_strError;};#endif // QWORD_H
word.cpp
#include "qword.h"
#include <QDateTime>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QDebug>
QWord::QWord(QObject *parent)
{m_word = new QAxObject(parent);m_documents = NULL;m_document = NULL;
}QWord::~QWord()
{close();
}bool QWord::createNewWord() //创建一个新的word
{//这种方式有些bug,选择路径取消会导致程序崩溃,直接传入路径,自己操作路径则不会出现问题/*QString defaultFileName = tr("测试记录%1").arg(QDateTime::currentDateTime().toString("yyyy年MM月dd日hh时mm分"));m_saveName=QFileDialog::getSaveFileName(0,"日志信息",defaultFileName,tr("*.doc"));QFile file(m_saveName);if(file.exists()){m_strError += "错误:目标文件已存在!";return false;}if(!m_saveName.isEmpty()){if(!m_word->setControl("Word.Application")){m_strError += "错误:获取word组件失败,请确定是否安装了word!";return false;}m_word->setProperty("Visible",false);m_word->setProperty("DisplayAlerts", false);//不显示任何警告信息。如果为true那么在关闭是会出现类似“文件已修改,是否保存”的提示m_documents = m_word->querySubObject("Documents");m_documents->dynamicCall("Add (void)");m_document = m_word->querySubObject("ActiveDocument");//获取当前激活的文档return true;}else{m_strError += "错误:文件名为空";return false;}*/
}
bool QWord::createNewWord(const QString& filePath )
{m_saveName = filePath;QFile file(m_saveName);if(file.exists()){m_strError += "错误:目标文件已存在!";return false;}if(!m_saveName.isEmpty()){if(!m_word->setControl("Word.Application")){m_strError += "错误:获取word组件失败,请确定是否安装了word!\n";return false;}m_word->setProperty("Visible",false);m_word->setProperty("DisplayAlerts", false);//不显示任何警告信息。如果为true那么在关闭是会出现类似“文件已修改,是否保存”的提示m_documents = m_word->querySubObject("Documents");if(!m_documents){m_strError += "获取文档失败!\n";return false;}m_documents->dynamicCall("Add (void)");m_document = m_word->querySubObject("ActiveDocument");//获取当前激活的文档return true;}else{m_strError += "错误:文件名为空";return false;}
}
//保存
void QWord::save()
{if(m_document)m_document->dynamicCall("Save()");elsereturn;
}
//关闭word
void QWord::close() //关闭 退出 析构时候也会自动调用一次
{if(!m_saveName.isEmpty()) //如果不为空 则为新建{saveAs();m_saveName = "";}if(m_document)m_document->dynamicCall("Close (boolean)",false);if(m_word)m_word->dynamicCall("Quit (void)");if(m_documents)delete m_documents;if(m_word)delete m_word;m_document = NULL;m_documents = NULL;m_word = NULL;
}
//另存为
void QWord::saveAs()
{if(m_document)m_document->dynamicCall("SaveAs(const QString&)",QDir::toNativeSeparators(m_saveName));elsereturn;
}
//设置页面1 横向还是 0竖向
void QWord::setPageOrientation(int flag)
{QAxObject* selection = m_word->querySubObject("Selection");QString page;switch (flag){case 0:page = "wdOrientPortrait";break;case 1:page = "wdOrientLandscape";break;}selection->querySubObject("PageSetUp")->setProperty("Orientation",page);
}
//设置页面视图
void QWord::setWordPageView(int flag)
{QAxObject* viewPage = m_word->querySubObject("ActiveWindow");QString view;switch (flag){case 1:view = "wdNormalView";break;case 2:view = "wdOutlineView";break;case 3:view = "wdPrintView";break;case 4:view = "wdPrintPreview";break;case 5:view = "wdMasterView";break;case 6:view = "wdWebView";break;case 7:view = "wdReadingView";break;case 8:view = "wdConflictView";break;}viewPage->querySubObject("View")->setProperty("Type",view);
}
//插入回车
void QWord::insertMoveDown()
{QAxObject* selection = m_word->querySubObject("Selection");selection->dynamicCall("TypeParagraph(void)");
}
//插入文字
void QWord::insertText(const QString& text)
{QAxObject* selection = m_word->querySubObject("Selection");selection->dynamicCall("TypeText(const QString&)",text);
}
//获取文本
QString QWord::GetText()
{QAxObject* selection = m_word->querySubObject("Selection");QString str = selection->dynamicCall("GetText(void)").toString();return str;
}
//设置文字对齐方向
void QWord::setParagraphAlignment(int flag)
{QAxObject* selection = m_word->querySubObject("Selection");if(flag == 0){selection->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphCenter");}else if(flag == 1){selection->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphJustify");}else if(flag == 2){selection->querySubObject("ParagraphFormat")->setProperty("Alignment","wdAlignParagraphRight");}
}
//设置字体大小
void QWord::setFontSize(int fontsize)
{QAxObject* selection = m_word->querySubObject("Selection");selection->querySubObject("Font")->setProperty("Size",fontsize);
}
//设置字体加粗
void QWord::setFontBold(bool flag)
{QAxObject* selection = m_word->querySubObject("Selection");selection->querySubObject("Font")->setProperty("Bold",flag);
}
//设置字体名称
void QWord::setFontName(QString& fontName)
{QAxObject* selection = m_word->querySubObject("Selection");selection->querySubObject("Font")->setProperty("Name",fontName);
}
//未知
void QWord::setSelectionRange(int start,int end)
{QAxObject* selection = m_word->querySubObject("Selection");selection->dynamicCall("SetRange(int, int)", start,end); //第1个字符后开始,到第9个字符结束范围
}
//未知
void QWord::getUsedRange(int *topLeftRow, int *topLeftColumn, int *bottomRightRow, int *bottomRightColumn)
{QAxObject* range = m_document->querySubObject("Range");*topLeftRow = range->property("Row").toInt();*topLeftColumn = range->property("Column").toInt();QAxObject *rows = range->querySubObject("Rows");*bottomRightRow = *topLeftRow + rows->property("Count").toInt() - 1;QAxObject *columns = range->querySubObject("Columns");*bottomRightColumn = *topLeftColumn + columns->property("Count").toInt() - 1;
}
//插入表格
void QWord::intsertTable(int row,int column)
{QAxObject* tables = m_document->querySubObject("Tables");QAxObject* selection = m_word->querySubObject("Selection");QAxObject* range = selection->querySubObject("Range");QVariantList params;params.append(range->asVariant());params.append(row);params.append(column);tables->querySubObject("Add(QAxObject*, int, int, QVariant&, QVariant&)", params);QAxObject* table = selection->querySubObject("Tables(1)");table->setProperty("Style","网格型");
}
//设置表格列宽
void QWord::setColumnWidth(int column, int width) //设置列宽
{QAxObject* selection = m_word->querySubObject("Selection");QAxObject* table = selection->querySubObject("Tables(1)");table->querySubObject("Columns(int)",column)->setProperty("Width",width);
}
//设置表格某行某列的字符串
void QWord::setCellString(int row, int column, const QString& text)
{QAxObject* selection = m_word->querySubObject("Selection");QAxObject* table = selection->querySubObject("Tables(1)");table->querySubObject("Cell(int, int)",row,column)->querySubObject("Range")->dynamicCall("SetText(QString)", text);
}
//设置表格内容粗体 isBold控制是否粗体
void QWord::setCellFontBold(int row, int column, bool isBold)
{QAxObject* selection = m_word->querySubObject("Selection");QAxObject* table = selection->querySubObject("Tables(1)");table->querySubObject("Cell(int, int)",row,column)->querySubObject("Range")->dynamicCall("SetBold(int)", isBold);
}
//设置表格文字大小
void QWord::setCellFontSize(int row, int column, int size)
{QAxObject* selection = m_word->querySubObject("Selection");QAxObject* table = selection->querySubObject("Tables(1)");table->querySubObject("Cell(int, int)",row,column)->querySubObject("Range")->querySubObject("Font")->setProperty("Size", size);
}
//获取单元格内容 此处对于Excel来说列和行从1开始最少
QVariant QWord::getCellValue(int row, int column)
{QAxObject* selection = m_word->querySubObject("Selection");QAxObject* table = selection->querySubObject("Tables(1)");return table->querySubObject("Cell(int, int)",row,column)->querySubObject("Range")->property("Text");
}
//获取表格数量
int QWord::getTableCount()
{QAxObject* tables = m_document->querySubObject("Tables");int val = tables->property("Count").toInt();return val;
}
//移动选定对象到文档末尾
void QWord::moveForEnd()
{QAxObject* selection = m_word->querySubObject("Selection");QVariantList params;params.append(6);params.append(0);selection->dynamicCall("EndOf(QVariant&, QVariant&)", params).toInt();
}
//表格插入图片
void QWord::insertCellPic(int row,int column,const QString& picPath)
{QAxObject* selection = m_word->querySubObject("Selection");QAxObject* table = selection->querySubObject("Tables(1)");QAxObject* range = table->querySubObject("Cell(int, int)",row,column)->querySubObject("Range");range->querySubObject("InlineShapes")->dynamicCall("AddPicture(const QString&)",picPath);
}
//未知
void QWord::setTableAutoFitBehavior(int flag)
{QAxObject* selection = m_word->querySubObject("Selection");QAxObject* table = selection->querySubObject("Tables(1)");if(0 <= flag & flag <= 2 )table->dynamicCall("AutoFitBehavior(WdAutoFitBehavior)", flag);
}
//删除选中列
void QWord::deleteSelectColumn(int column)
{QAxObject* selection = m_word->querySubObject("Selection");QAxObject* table = selection->querySubObject("Tables(1)");QAxObject* columns = table->querySubObject("Columns(int)",column);columns->dynamicCall("Delete()");
}void QWord::setOptionCheckSpell(bool flags)
{QAxObject* opetions = m_word->querySubObject("Options");if(!opetions)return;opetions->setProperty("CheckGrammarAsYouType",flags);opetions->setProperty("CheckGrammarWithSpelling",flags);opetions->setProperty("ContextualSpeller",flags);opetions->setProperty("CheckSpellingAsYouType",flags);
}
void QWord::inserttestdata(testDataType &str)
{//先创建固定表头等内容setPageOrientation(0); //页面纵向setWordPageView(3); //页面视图insertMoveDown(); //插入回车setFontSize(25); //字体大小setParagraphAlignment(0); //下面文字置中setFontBold(true); //字体加粗insertText(QString("xxx检测报告"));//插入文字setFontBold(false); //字体加粗insertMoveDown(); //插入回车setParagraphAlignment(1); //下面文字置左setFontSize(16); //字体大小insertText(QString("检测人员:%1").arg(str.user));//插入文字insertMoveDown(); //插入回车insertText(QString("xxx编号:%1").arg(str.code));//插入文字insertMoveDown(); //插入回车insertText(QString("xxx完好度:%1%").arg(str.fenshu));//插入文字insertMoveDown(); //插入回车insertText(tr("检测日期:%1").arg(QDateTime::currentDateTime().toString("yyyy年MM月dd日 hh时mm分")));//插入文字setFontSize(12); //字体大小insertMoveDown(); //插入回车
// insertText(QString("——————————————————————————————————"));//插入文字
// insertMoveDown(); //插入回车setParagraphAlignment(0); //下面文字置中intsertTable(55,3);//插入表格 55行 3列setColumnWidth(1,50);//设置表格列宽 第1列setColumnWidth(2,300);//设置表格列宽 第1列setColumnWidth(3,100);//设置表格列宽 第1列setCellString(1,1,"序号");//设置表格某行某列的字符串 1行1列 设置内容setCellString(1,2,"信号名称");//设置表格某行某列的字符串 1行2列 设置内容setCellString(1,3,"信号状态");//设置表格某行某列的字符串 1行3列 设置内容setCellFontBold(1,1,true);//设置表格内容粗体 isBold控制是否粗体 1行1列 粗体setCellFontBold(1,2,true);//设置表格内容粗体 isBold控制是否粗体 1行2列 粗体setCellFontBold(1,3,true);//设置表格内容粗体 isBold控制是否粗体 1行3列 粗体setCellFontSize(1,1,12);//设置表格文字大小 1行1列 16号setCellFontSize(1,2,12);//设置表格文字大小 1行2列 16号setCellFontSize(1,3,12);//设置表格文字大小 1行3列 16号for(int i=0;i<54;i++)setCellString(i+2,1,QString::number(i+1));//设置表格某行某列的字符串 1行1列 设置内容setCellString(2,2,"电源电压");//设置表格某行某列的字符串setCellString(2,3,result[str.res_power1]);//设置表格某行某列的字符串for(int i=0;i<16;i++){setCellString(3+i,2,QString("%1传感器电源").arg(cgq_name[i]));//设置表格某行某列的字符串setCellString(3+i,3,result[str.res_power[i]]);//设置表格某行某列的字符串}for(int i=0;i<16;i++){setCellString(3+16+i,2,QString("%1传感器信号").arg(cgq_name[i]));//设置表格某行某列的字符串setCellString(3+16+i,3,result[str.res_value[i]]);//设置表格某行某列的字符串}for(int i=0;i<3;i++){setCellString(3+16+16+i,2,QString("%1报警信号").arg(warnname[i]));//设置表格某行某列的字符串setCellString(3+16+16+i,3,result[str.res_warn[i]]);//设置表格某行某列的字符串}for(int i=0;i<2;i++){setCellString(3+16+16+3+i,2,QString("%1信号").arg(tempname[i]));//设置表格某行某列的字符串setCellString(3+16+16+3+i,3,result[str.res_temp[i]]);//设置表格某行某列的字符串}xxx内容根据自己需求自行添加moveForEnd();//移动选定对象到文档末尾insertMoveDown(); //插入回车setParagraphAlignment(2); //下面文字置右setFontSize(14);insertText("测试人员签字:_______________");insertMoveDown();insertText("年 月 日");
}
其中inserttestdata函数为外部调用入口函数,根据需要导出的信息内容自行更改改函数,编辑word格式,入口参数模版程序中我使用的是结构体,将所有数据赋值到结构体中在调用保存输出word
inserttestdata入口函数方式二:
void QWord::insertselfdata(selfDataType &str)
{//先创建固定表头等内容setPageOrientation(0); //页面纵向setWordPageView(3); //页面视图insertMoveDown(); //插入回车setFontSize(25); //字体大小setParagraphAlignment(0); //下面文字置中setFontBold(true); //字体加粗insertText(QString("xxxxxx输出报表"));//插入文字setFontBold(false); //字体加粗insertMoveDown(); //插入回车setParagraphAlignment(1); //下面文字置左setFontSize(16); //字体大小insertText(QString("xx人员:%1").arg(str.user));//插入文字setFontSize(12); //字体大小insertMoveDown(); //插入回车insertText(QString("——————————————————————————————————"));//插入文字insertMoveDown(); //插入回车setFontSize(16); //字体大小insertText(QString("被测设备编号:%1").arg(str.number));//插入文字insertMoveDown(); //插入回车insertText(tr("xx日期:%1").arg(QDateTime::currentDateTime().toString("yyyy年MM月dd日 hh时:mm分")));//插入文字setFontSize(12); //字体大小insertMoveDown(); //插入回车insertText(QString("——————————————————————————————————"));//插入文字insertMoveDown(); //插入回车//添加自检数据内容QString tabname[24]={xxxx};insertText(tr("xxxx检测结果"));insertMoveDown(); //插入回车for(int i=0;i<24;i++){insertText(tr("%1:%2").arg(tabname[i]).arg(str.value[i])); //插入文字insertMoveDown(); //插入回车}insertText(QString("——————————————————————————————————"));//插入文字insertMoveDown(); //插入回车
}
调用程序.cpp
QString dir = QFileDialog::getExistingDirectory(this, tr("选择信息导出文件目录"),"/home",QFileDialog::ShowDirsOnly|QFileDialog::DontResolveSymlinks);QString filePath = QString(dir+"/"+"测试数据%1.docx").arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"));QFile file(filePath);if(dir.isEmpty())massage_dialog(1,"提示","数据保存失败!未选择保存路径!",0,0);else if(file.exists())massage_dialog(1,"提示","数据保存失败!保存路径下存在相同文件!",0,0);QWord word;word.createNewWord(filePath); //创建一个新的wordword.inserttestdata(testdata); //写入数据word.close(); //关闭wordmassage_dialog(1,"提示","数据测试文件生成成功!",0,0);
调用程序方式二:
QString dir = historypath;//已经确认好的历史数据地址QDir dir1(dir);QString filePath = QString(dir+"/"+"xxx检测报告%1.docx").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh-mm-ss"));QFile file(filePath);if(dir.isEmpty())massage_dialog(1,"提示","生成报告失败!保存路径为空!请前往系统设置界面设定报告保存路径!检查数据库文件是否存在!",1);else if(!dir1.exists())massage_dialog(1,"提示","生成报告失败!保存路径丢失!请前往系统设置界面设定报告保存路径!",1);else if(file.exists())massage_dialog(1,"提示","生成报告失败!保存路径下存在相同文件!",1);else//这里输出word和保存数据库{///赋值当前数据到缓存区testDataType testdata;testdata.user=Data_user.now_username;testdata.code=machinecode;testdata.fenshu=QString::number(fenshu);testdata其余结构体数据赋值///保存wordQWord word;if(word.createNewWord(filePath)){//创建一个新的wordword.inserttestdata(testdata); //写入数据}elsemassage_dialog(1,"提示","错误:获取word组件失败,请确定是否安装了word!",1);word.close();//关闭wordmassage_dialog(1,"提示",QString("导出报告成功!文件导出位置:%1").arg(filePath),1);ui->btn_report->setEnabled(false);}
导出word效果:
qt导出word模板(模块化程序,直接调用保存数据到指定路径)相关推荐
- poi导出word模板
**poi导出word模板段落处理 流程: 1:读取文档:` //获取docx解析对象 XWPFDocument document = new XWPFDocument(POIXMLDocument. ...
- SpringBoot导出word模板并动态渲染数据
导出word模板并动态渲染数据 一.需求介绍 背景:需要导出word模板的时候,有些数据是动态或者图片等不确定因素的时候.根据需求定制好的模板要求填充数据,那么这个时候就需要进行根据word模板进行动 ...
- Freemarker使用mht制作导出word模板
Freemarker使用mht制作导出word模板 一.制作word导出模板时,我们使用官方的Office Word编辑样式,编辑好之后,另存为mhtml格式,这样我们就可以看到源代码了.注意:创建w ...
- Springboot 项目导出word文档(文档内容包括数据以及服务器图片)
Springboot 项目freemarker导出word文档(文档内容包括数据以及服务器图片) 前些天有需求要完成导出word文档功能,基础数据导出word文档,网上也能搜到很多源代码,但是我这边要 ...
- UOS使用命令调用文件管理器打开指定路径的方法
语法如下: dde-file-manager <路径> 例如: dde-file-manager /home/liumou/ 麒麟的方法如下: 麒麟kylin使用命令调用文件管理器打开指定 ...
- java修改导出模板,java模板导出word模板 java根据word模板导出
java 调用word模板实现循环套打生成word文档 首先我用的技术是 poi 这是代码,一个工具类得调用 public class WordUtil { /** * 基于模板文件导出 word 文 ...
- springboot+freemarker实现导出word模板
freemarker FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页.电子邮件.配置文件.源代码等)的通用工具. 它不是面向最终用户的,而是一个 ...
- Freemarker模板引擎:使用HashMap数据形式,导出word模板
编写:HorinJsor 文章目录 一.Freemarker是什么? 二.Word模板编写 1.导出为xml格式文档 在这里插入图片描述 2.使用HBuilderX重排格式 3.基本模板语法 三.代码 ...
- 【Java】poi-tl实现导出Word模板并动态渲染数据
文章目录 前言 优点 缺点 使用 引入依赖 渲染普通占位符 表格渲染 前言 最近做项目的时候会遇到要求要导出以docx格式结尾的报告文件,于是我就在思考有没有一个比较好用的第三方类库能解决在word上 ...
- (半成品)Excel文件按要求导出至模板excel中(含配套数据)
Task:Excel文件按要求导出至模板excel中 要求其实挺多的,一下次也说不完,大致情况如下图所示 数据:配套数据下载链接(如未审核完成,请评论留言邮箱给我哈) 思路: 用openpyxl库筛选 ...
最新文章
- WideCharToMultiByte和MultiByteToWideChar函数的用法(ascii转unicode unicode转ascii)
- 原型设计工具【收集转帖】
- [译] APT分析报告:03.OpBlueRaven揭露APT组织Fin7/Carbanak(上)Tirion恶意软件
- 在 IE 中使用 HTML5 元素
- spring boot + vue 前后端分离时间戳转换为 yyyy:MM:dd HH:mm:ss格式
- HDU - 1054 Strategic Game (二分图匹配模板题)
- 求职必看!大厂面试中遇到了发散性问题..... ,怎么办?
- 印象笔记粘贴HTML,印象笔记剪藏插件
- Android release apk 签名流程
- Eclipse 快捷键设置
- 【深度学习】使用opencv在视频上添加文字和标记框
- 钢笔墨水能否代替打印机墨水_打印机墨水怎么分类?
- 麻木的IT公民:293个公司人压力和心理调查
- 华师在线计算机网络,华师在线-作业计算机网络.docx
- Spring系列教程六: Spring jdbcTemplate在Dao中的使用
- 【网络攻防技术】实验九——嗅探与欺骗实验
- Python网络编程之初识
- flutter 自定义 Toast
- 通用进制转换工具,可实现进制之间的任意转换
- private vlan(私有vlan)