目录

  • 实现思路
    • 1. UI截图
    • 2. 使用Aspose.Words创建表格
  • 详细实现
    • 使用Aspose.Words将创建的表格和其他文本数据、图片插入到Word中
    • WriteDataToXML.cs将对象序列化为xml数据
    • WriteDataToWord.cs解析xml画出表格插入到word文件中
  • 运行结果:
  • 使用Texture2D.ReadPixels进行指定UI界面截图
  • 需要注意的点

实现思路

1. UI截图

这是实现的是针对某一特定的UI截图,实际上是使用了通过Unity中的API:Texture2D.ReadPixels来读取屏幕区域像素,然后将图片数据转为二进制数据,再保存到本地。

2. 使用Aspose.Words创建表格

Aspose.Words是一款先进的类库,可以直接在各个应用程序中执行各种文档处理任务。Aspose.Words支持DOC,OOXML,RTF,HTML,OpenDocument, PDF, XPS, EPUB和其他格式。使用Aspose.Words,不使用Microsoft Word和WPS。也可以生成,更改,转换,渲染和打印文档。
这里应用到Unity中,将文本数据、图片和使用Aspose.Words创建的表格插入到模板Word中。使用数据分离的方法,首先定义表格数据类TableData,在这个类中,定义你的表名、表头、表格内容等等,然后有一个方法是你要从其他模块里将获取到的表格数据保存到这个类TableData的数据结构中,再根据这些数据创建表格数据的xml节点信息并保存下来,另外一个脚本里写解析这个xml文档的方法,根据解析出来的数据,利用Aspose.Words类库里的API创建表格并插入各种数据。最后使用FileBrowser插件打开本地资源浏览器并保存新的Word文档。

详细实现

使用Aspose.Words将创建的表格和其他文本数据、图片插入到Word中

  • 首先明确你要创建的表格长啥样?这决定了你的TableData类要怎么写。
    比如我需要创建如下两个表格:


    那就要归纳出来我的数据结构应该包含:表格名称、表头、表格内容、表尾这些信息,明确了这些信息,那我构造出来的TableData应该是这样的:
  • 获取表格数据保存到TableData类数据结构中
    你的表名是什么,表头、表格内容等这些数据都是需要提前获取的,这决定了你要生成多少行表格数据,我这里只是演示demo,所以直接写好测试数据:
  • 将表格数据转为xml的形式保存下来
    完整代码:

WriteDataToXML.cs将对象序列化为xml数据

using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using System.Linq;
/// <summary>
/// 将数据写入XML文档
/// </summary>
public class WriteDataToXML : MonoBehaviour
{/// <summary>/// 文档所在目录/// </summary>string wordXMLPath;/// <summary>/// 写入到 xml中的数据/// </summary>List<TableData> tableDatas=new List<TableData>();string[] table1HeaderName = { "序号", "姓名","语文", "数学", "英语"};string[] table2HeaderName = { "序号", "姓名", "性别", "总分"};/// <summary>/// 表格中每一行的数据,序号在创建表格的时候直接写入/// 初始化一个二维数组,存储表格数据/// </summary>string[,] tableRowDatas = { { "周一","男", "90","90", "60","240" },{ "卓二","女", "100","90","70" ,"260" },{ "张三","女", "80","60", "65" ,"205"},{ "李四","男", "90","60", "80" ,"230"},{ "王五","男", "70","80", "80","230" }};string[] textDatas = { "初一(5)班", "300" };private void Start(){wordXMLPath = Application.dataPath + "/../data/Word";}/// <summary>/// 保存Word/// </summary>public void SaveWord(){CreateTableData(table1HeaderName,1);CreateTableData(table2HeaderName, 2);CreateXmlData();SaveWordToWindow.WriteDataToWord a = new SaveWordToWindow.WriteDataToWord();a.CreateNewWord(wordXMLPath);}/// <summary>/// 创建表格数据/// 前提是拿到数据来源/// </summary>/// <param name="datas">表头数据</param>/// <param name="tableId">表格的ID</param>private void CreateTableData(string[] datas,int tableId){TableData TData = new TableData();for (int i = 0; i < datas.Length; i++){TData.TableHeaderList.Add(datas[i]);//添加一个表头}if (tableId==1)//获取表格1数据{TData.tableName = "班级个人单科成绩表";for (int i = 0; i < tableRowDatas.GetLength(0); i++){//表格每一行的数据,从左到右List<string> rowDatas = new List<string>();rowDatas.Add(tableRowDatas[i, 0]);//即姓名rowDatas.Add(tableRowDatas[i, 2]);//即语文成绩rowDatas.Add(tableRowDatas[i, 3]);//即数学成绩rowDatas.Add(tableRowDatas[i, 4]);//即英语成绩TData.TBodyList.Add(rowDatas);}}else if(tableId==2)//获取表格2数据{TData.tableName = "班级总分表";TData.TableTail = "最高分";List<int> array=new List<int>();for (int i = 0; i < tableRowDatas.GetLength(0); i++){List<string> rowDatas = new List<string>();rowDatas.Add(tableRowDatas[i, 0]);//即姓名rowDatas.Add(tableRowDatas[i, 1]);//即性别rowDatas.Add(tableRowDatas[i, 5]);//即总分TData.TBodyList.Add(rowDatas);array.Add(int.Parse(tableRowDatas[i, 5]));}TData.FooterStr = array.Max().ToString();//使用了Linq的Max()方法找到最大值}tableDatas.Add(TData);//将一个表格数据添加到表格列表}/// <summary>/// 创建表格数据的xml节点信息并保存/// </summary>private void CreateXmlData(){XmlDocument xmlDoc = new XmlDocument();xmlDoc.AppendChild(xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null));//创建xml文件声明XmlElement rootNode = xmlDoc.CreateElement("Root");//创建根节点xmlDoc.AppendChild(rootNode);//将根节点添加到xml中XmlElement wordNode = xmlDoc.CreateElement("WordName");wordNode.InnerText = "班级成绩报告.doc";rootNode.AppendChild(wordNode);//根据表格数据创建表格的xml数据for (int i = 0; i < tableDatas.Count; i++){//创建一个表格的xml信息TableData tableData = tableDatas[i];XmlElement tableNode = xmlDoc.CreateElement("Table");tableNode.SetAttribute("LabelName", string.Format("table{0}", i + 1));rootNode.AppendChild(tableNode);//创建表名节点XmlElement TNameNode = xmlDoc.CreateElement("TableName");TNameNode.InnerText = tableData.tableName;tableNode.AppendChild(TNameNode);//创建表头节点XmlElement headerNode = xmlDoc.CreateElement("HeaderName");tableNode.AppendChild(headerNode);for (int j = 0; j < tableData.TableHeaderList.Count; j++){XmlElement itemNode = xmlDoc.CreateElement("Item");itemNode.InnerText = tableData.TableHeaderList[j];headerNode.AppendChild(itemNode);}//创建表格内容的节点XmlElement dataNode = xmlDoc.CreateElement("Data");tableNode.AppendChild(dataNode);for (int lineIdx = 0; lineIdx < tableData.TBodyList.Count; lineIdx++){//一行对应一个Line节点XmlElement lineNode = xmlDoc.CreateElement("Line");dataNode.AppendChild(lineNode);for (int cell = 0; cell < tableData.TableHeaderList.Count-1; cell++){//行内一个单元格对应一个Item节点XmlElement itemNode = xmlDoc.CreateElement("Item");itemNode.InnerText = tableData.TBodyList[lineIdx][cell];lineNode.AppendChild(itemNode);}}//创建表尾节点XmlElement tailNode = xmlDoc.CreateElement("TailName");tailNode.SetAttribute("LabelName", tableData.TableTail);tailNode.InnerText = tableData.FooterStr;tableNode.AppendChild(tailNode);}//创建其他文本数据节点XmlElement textNode = xmlDoc.CreateElement("Text");for (int i = 0; i < textDatas.Length; i++){XmlElement itemNode = xmlDoc.CreateElement("Item");itemNode.SetAttribute("LabelName", string.Format("text{0}",i));itemNode.InnerText = textDatas[i];textNode.AppendChild(itemNode);}rootNode.AppendChild(textNode);//创建图片信息节点XmlElement pictureNode = xmlDoc.CreateElement("Picture");pictureNode.SetAttribute("LabelName", "image");pictureNode.InnerText = "picture";rootNode.AppendChild(pictureNode);string docPath = wordXMLPath + "/WordData.xml";xmlDoc.Save(docPath);//将所以表格数据保存到本地WordData.xml文件中}
}
/// <summary>
/// 表格数据类
/// </summary>
public class TableData
{/// <summary>/// 表名/// </summary>public string tableName;/// <summary>/// 表头数据/// </summary>public List<string> TableHeaderList=new List<string>();/// <summary>/// 表格每一行的内容/// </summary>public List<List<string>> TBodyList=new List<List<string>>();/// <summary>/// 表尾/// </summary>public string TableTail { get; set; }/// <summary>/// 表尾内容/// </summary>public string FooterStr;
}

将脚本挂载到物体上,在保存报告的按钮上添加监听SaveWord方法:

运行可以看到生成的WordData.xml内容:

WriteDataToWord.cs解析xml画出表格插入到word文件中

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using Crosstales.FB;
using Aspose.Words;namespace SaveWordToWindow
{public class WriteDataToWord{/// <summary>/// 模板Word文件名/// </summary>public string WordName;/// <summary>/// 插入到word中的文本数据信息/// </summary>public List<OtherData> textDatas = new List<OtherData>();/// <summary>/// 插入到word中的图片数据信息/// </summary>public List<OtherData> pictureDatas = new List<OtherData>();/// <summary>/// 插入到word中的表格数据信息/// </summary>public List<Table> tableDatas = new List<Table>();public string filePath = "";/// <summary>/// 生成一个新的Word文档,并可选择本地路径保存/// </summary>public void CreateNewWord(string path){filePath = path;LoadingWordDataXML(path);InsertDataToWord();}/// <summary>/// 解析需要插入到Word中的数据信息节点  /// </summary>/// <param name="path"></param>private void LoadingWordDataXML(string path){XmlDocument doc = new XmlDocument();doc.Load(path+ "/WordData.xml");XmlNode node = doc.SelectSingleNode("Root");foreach (XmlNode item in node.ChildNodes){switch (item.Name){case "WordName":WordName = item.InnerText;break;case "Table":ReadTableData(item);break;case "Text":ReadTextData(item);break;case "Picture":ReadPictureData(item);break;}}}/// <summary>/// 读取xml中的表格数据节点/// </summary>/// <param name="node"></param>private void ReadTableData(XmlNode node){Table table = new Table();table.TableTagName = node.Attributes["LabelName"].InnerText;table.TableName = node.SelectSingleNode("TableName").InnerText;foreach (XmlNode item in node.ChildNodes){switch (item.Name){case "HeaderName":table.TableHeader = new List<string>();for (int i = 0; i < item.ChildNodes.Count; i++){table.TableHeader.Add(item.ChildNodes[i].InnerText);}break;case "Data":table.TableData = new List<List<string>>();for (int i = 0; i < item.ChildNodes.Count; i++){List<string> rowData = new List<string>();for (int j = 0; j < item.ChildNodes[i].ChildNodes.Count; j++){rowData.Add(item.ChildNodes[i].ChildNodes[j].InnerText);}table.TableData.Add(rowData);}break;case "TailName":table.TableTail = item.Attributes["LabelName"].InnerText;table.TableTailData = item.InnerText;break;}}tableDatas.Add(table);}/// <summary>/// 读取xml中的图片数据节点/// </summary>/// <param name="node"></param>private void ReadPictureData(XmlNode node){OtherData pData = new OtherData();pData.labelName = node.Attributes["LabelName"].InnerText;pData.Data = node.InnerText;pictureDatas.Add(pData);}/// <summary>/// 读取xml中的文本数据节点/// </summary>/// <param name="node"></param>private void ReadTextData(XmlNode node){foreach (XmlNode item in node.ChildNodes){OtherData textData = new OtherData();textData.labelName = item.Attributes["LabelName"].InnerText;textData.Data = item.InnerText;textDatas.Add(textData);}}/// <summary>/// 将数据插入到Wordw文档中/// </summary>private void InsertDataToWord(){//以WordName的word文件为模板Document doc = new Document(filePath + "\\" + WordName);//使用DocumentBuilder将各种数据插入到Word中DocumentBuilder docBuilder = new DocumentBuilder(doc);//插入文本数据for (int i = 0; i < textDatas.Count; i++){try{//获取到文档中textDatas[i].labelName标签Bookmark bookMark = doc.Range.Bookmarks[textDatas[i].labelName];if (bookMark != null){bookMark.Text = "";//清除标示//移动到书签 textDatas[i].labelName处if (docBuilder.MoveToBookmark(textDatas[i].labelName)){docBuilder.Write(textDatas[i].Data);//插入数据}}}catch (System.Exception e){Debug.Log("插入文本数据异常" + e.Message);}}//插入图片for (int i = 0; i < pictureDatas.Count; i++){try{Bookmark bookmark = doc.Range.Bookmarks[pictureDatas[i].labelName];if (bookmark != null){bookmark.Text = "";if (docBuilder.MoveToBookmark(pictureDatas[i].labelName)){string imgPath = string.Format("{0}\\{1}.png", filePath, pictureDatas[i].Data);docBuilder.InsertImage(imgPath);}}}catch (System.Exception e){Debug.Log("插入图片异常" + e.Message);}}//生成表格并插入for (int i = 0; i < tableDatas.Count; i++){try{Table tableData = tableDatas[i];//用来设置表格中的单元格宽度int[] lens = { 10, 20, 20, 20, 20 };Bookmark bookmark = doc.Range.Bookmarks[tableData.TableTagName];if (bookmark != null){bookmark.Text = "";if (docBuilder.MoveToBookmark(tableData.TableTagName)){//开始创建表格docBuilder.StartTable();//生成表格表名for (int iName = 0; iName < tableData.TableHeader.Count; iName++){docBuilder.InsertCell();//插入单元格docBuilder.CellFormat.Width = lens[iName];//设置单元格宽度docBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Center;//设置单元格水平居中对齐if (iName == 0){docBuilder.Write(tableData.TableName);//写入内容docBuilder.CellFormat.HorizontalMerge = Aspose.Words.Tables.CellMerge.First;//横向合并第一个单元格}else{//与前一个单元格合并,无需再写入内容docBuilder.CellFormat.HorizontalMerge = Aspose.Words.Tables.CellMerge.Previous;}}//结束一行,并开始新的一行docBuilder.EndRow();//生成表头for (int iHead = 0; iHead < tableData.TableHeader.Count; iHead++){docBuilder.InsertCell();//这里不单元格合并,所以需设置为None,否则会与前面的单元格合并docBuilder.CellFormat.HorizontalMerge = Aspose.Words.Tables.CellMerge.None;docBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Center;docBuilder.Write(tableData.TableHeader[iHead]);docBuilder.CellFormat.Width = lens[iHead];}docBuilder.EndRow();//生成表格内容for (int iRow = 0; iRow < tableData.TableData.Count; iRow++){//生成表示序号的单元格docBuilder.InsertCell();docBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Center;docBuilder.Write(string.Format("{0}", iRow + 1));docBuilder.CellFormat.Width = lens[0];List<string> cells = tableData.TableData[iRow];//生成每一行的每一个单元格的内容for (int iCell = 0; iCell < cells.Count; iCell++){docBuilder.InsertCell();docBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Center;docBuilder.Write(cells[iCell]);docBuilder.CellFormat.Width = lens[iCell + 1];}docBuilder.EndRow();}//判断是否有表尾if (!string.IsNullOrEmpty(tableData.TableTail)){//生成表尾,表尾的第一个单元格与倒数第二个单元格需要合并,写入表尾名称//最后一个单元格无需合并,写入表尾数据for (int iTail = 0; iTail < tableData.TableHeader.Count; iTail++){docBuilder.InsertCell();docBuilder.CellFormat.Width = lens[iTail];docBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Center;if (iTail == 0){docBuilder.Write(tableData.TableTail);//横向合并的第一个单元格docBuilder.CellFormat.HorizontalMerge = Aspose.Words.Tables.CellMerge.First;}else if (iTail > 0 && iTail < tableData.TableHeader.Count - 1){//与前一个单元格合并docBuilder.CellFormat.HorizontalMerge = Aspose.Words.Tables.CellMerge.Previous;}else{docBuilder.Write(tableData.TableTailData);//最后一个单元格无需合并docBuilder.CellFormat.HorizontalMerge = Aspose.Words.Tables.CellMerge.None;}}}docBuilder.EndRow();//结束当前表格docBuilder.EndTable();}}}catch (System.Exception e){Debug.Log("插入表格异常" + e.Message);}}//另存为一个更新后的Word文档,并可以选择路径保存string extensions = "doc";//这里用到了FileBrowser插件,用于打开本地资源浏览器保存文件doc.Save(FileBrowser.SaveFile("保存Word", "", "MySaveFile", extensions));}}/// <summary>/// 其他数据/// </summary>public class OtherData{/// <summary>/// 标签名/// </summary>public string labelName;/// <summary>/// 数据信息/// </summary>public string Data;}/// <summary>/// 表格数据/// </summary>public class Table{/// <summary>/// 表格名/// </summary>public string TableName;/// <summary>/// 表格标签/// </summary>public string TableTagName;/// <summary>/// 表头/// </summary>public List<string> TableHeader;/// <summary>/// 表格内容/// </summary>public List<List<string>> TableData;/// <summary>/// 表尾/// </summary>public string TableTail;/// <summary>/// 表尾内容/// </summary>public string TableTailData;}
}

注释写的很明白了,首先解析在xml中的表格信息、文本信息、图片信息,分别保存到Table类和OtherData类的数据结构中去,最后根据这些数据创建一个个单元格,写入内容,插入文本和图片到Word中,并可另存到本地。

  • 模板Word中的标签要与xml文档中生成的一致
    添加标签:

运行结果:

代码对应生成的数据:


使用Texture2D.ReadPixels进行指定UI界面截图

ScreenShotByUI.cs

using UnityEngine;
using System.Collections;
public class ScreenShotByUI : MonoBehaviour
{/// <summary>/// 截图的UI/// </summary>public RectTransform ScreenShotUI;//保存的图片路径string picturePath;/// <summary>/// 点击开始截图方法/// </summary>public void ScreenShotClick(){picturePath = Application.dataPath + "/../data/Word/picture.png";IEnumerator coroutine = ScreenShot(ScreenShotUI, picturePath);StartCoroutine(coroutine);}/// <summary>/// 异步读取UI像素转为字节流数据并保存/// </summary>/// <param name="ScreenShotUI"></param>/// <param name="mFileName">保存截图的路径名</param>/// <returns></returns>public IEnumerator ScreenShot(RectTransform ScreenShotUI, string mFileName){//等待帧画面渲染结束yield return new WaitForEndOfFrame();int uiWidth = (int)(ScreenShotUI.rect.width);int uiHeight = (int)(ScreenShotUI.rect.height);Texture2D tex = new Texture2D(uiWidth, uiHeight, TextureFormat.RGB24, false);//左下角为原点(0, 0)float uiLeftX = ScreenShotUI.transform.position.x + ScreenShotUI.rect.xMin;float uiLeftY = ScreenShotUI.transform.position.y + ScreenShotUI.rect.yMin;//从屏幕读取像素, leftBtmX/leftBtnY 是读取的初始位置,width、height是读取像素的宽度和高度//可以根据需求更改宽高tex.ReadPixels(new Rect(uiLeftX, uiLeftY, uiWidth, uiHeight), 0, 0);//执行读取操作tex.Apply();//将纹理图片转为字节流数据byte[] bytes = tex.EncodeToPNG();//将字节流数据保存到本地System.IO.File.WriteAllBytes(mFileName, bytes);}
}

将脚本拖拽到游戏物体上,将要截图的UI拖拽到ScreenShotUI处:

运行可以看到图片保存到本地了:

需要注意的点

  • 创建表格和插入图片用到的两个DLL文件:Aspose.Words和System.Drawing

    需在.net3.5平台下运行,且要注意编辑器是32位还是64位,dll设置里勾选对应的we如果不是,得在设置里修改:

  • Word设置的标签要与代码里写的一致,且不能使用中文,因为aspose.words不支持。
    Aspose.word和system.drawing下载

Unity使用Aspose.Words创建表格和UI截图一起插入到Word中并保存到本地的一种解决方案相关推荐

  1. Aspose.Words 创建表格

    1 使用详解 (1)StartTable() 说明:创建表格. 格式:public Table StartTable(); (2)InsertCell() 说明:在当前位置插入表格单元格. 格式:pu ...

  2. 利用aspose.words指定表格 复制行 并动态插入数据

    1.在pom.xml添加依赖 <dependency><groupId>aspose.words</groupId> <!--自定义--><art ...

  3. python生成word文档的表格_说说如何使用 Python 在 word 中创建表格

    我们可以使用 python-docx 模块,实现在 word 中创建表格. 请看下面这段代码: table = doc.add_table(rows=1, cols=len(titles)) # 设置 ...

  4. FineUIMvc随笔(1)动态创建表格列

    声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. <FineUIMvc随笔>目录 FineUIMvc随笔(1)动态创建表格列 FineUIMvc随笔(2)怎样在控件中 ...

  5. Python代码创建表格

    Python代码创建表格 简介 在数据分析和处理的工作中,常常需要将数据整理成表格的形式,方便查看和分析.Python作为一门流行的编程语言,提供了多种创建表格的工具和库,极大地方便了数据处理的工作. ...

  6. word文档通配符换行_职场小技巧|没想到word中的表格就可以排版图片大小

    不知道大家在工作当中有没有遇到这样的情况:在WORD文档中想插入图片,却不能保证大小格式一样怎么办?如果数量较少的话,我相信大家还是有办法解决的!比如可以先插入一张图片后设置统一的格式进使用快捷键F4 ...

  7. poi 设置word表格颜色_办公软件小课堂 Word表格的设置

    你是否还在为考证烦恼?是否不知从何学起?学习部每周的办公软件小课堂!这里总有你想要的! 本周给大家整理的是 Word表格的设置 01 插入选择卡→表格 02 文本转表格 步骤1:选中要转换成表格的文本 ...

  8. html打印预览出现重叠,求高手解答:在WORD 中插入EXCEL表格,打印出现字重叠的问题...

    求高手解答:在WORD 中插入EXCEL表格,打印出现字重叠的问题以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 求高手 ...

  9. Unity UI -- (7) 创建世界空间UI

    目前为止,我们已经设计了一个屏幕空间UI(Screen Space UI).一个屏幕空间UI会在屏幕上平坦放置,它会被渲染到环境中所有东西的上面,无论相机位置在哪里. 而一个世界空间UI(World ...

  10. Unity实用功能之读写Excel表格

    概述 在项目开发过程中,经常会用到大量的可编辑的数据,而这些数据使用Json,XML等形式存储又比较麻烦 PS:对于不懂电脑的客户来说完全就是看天书,后期编辑也比较费事.所以就有了使用Excel表格进 ...

最新文章

  1. 软件BT是硬盘杀手?
  2. 处理json中影响解析的多余引号
  3. Java Arrays.asList注意事项
  4. MySQL外键关联(一对多)MySQL连接查询
  5. 洛谷 P1273 【有线电视网】
  6. Java多线程 ——线程基础和锁锁锁
  7. [JS基础] 之类型判断
  8. 关于Java中的对象的哈希值何时相等
  9. Python爬虫实战源码合集(持续更新)
  10. 【知识图谱】一文全览,ICLR 2020 上的知识图谱研究
  11. WPF 获取控件模板中的控件
  12. Java用户管理系统
  13. 安卓 VNET 抓取 wskey 教程
  14. 什么是云服务器ECS?
  15. 常用网络命令:ping命令的使用
  16. RTX3050、3050Ti相当于什么水平?
  17. 3、Nginx系列之: location和alias的区别
  18. 7-9 彩虹瓶 (25 分)(c++)
  19. 操作系统 进程调度之轮换调度(RR调度)
  20. 有道云笔记4年的用户体验

热门文章

  1. 华为手机安装GMS框架
  2. STM8L低功耗停止看门狗
  3. Java拼接sql,并组装成建表语句
  4. LTE学习笔记:LTE总体架构
  5. 浅谈声纹识别应用:声音被模仿,声音识别身份可靠吗?
  6. Bus Hound(USB抓包工具)
  7. 利用高德制作GIS热力图
  8. 分享116个PHP源码PHP源码,总有一款适合你
  9. 直播预告丨技术干货:易鲸捷HTAP融合型分布式数据库连接服务层介绍
  10. cada0图纸框_a0标准图框|autocad a0标准图纸框模板下载免费版 - 欧普软件下载