Java实现在线编辑预览office文档
文章目录
- 1 在线编辑
- 1.1 PageOffice简介
- 1.2 前端项目
- 1.2.1 配置
- 1.2.2 页面部分
- 1.3 后端项目
- 1.3.1 pom.xml
- 1.3.2 添加配置
- 1.3.3 controller
- 2 在线预览
- 2.1 引言
- 2.2 市面上现有的文件预览服务
- 2.2.1 微软
- 2.2.2 Google Drive查看器
- 2.2.3 阿里云 IMM
- 2.2.4 XDOC 文档预览
- 2.2.5 Office Web 365
- 2.2.6 WPS开放平台
- 2.3 前端处理方案
- 2.3.1 pptx的预览方案
- 2.3.2 pdf的预览方案
- 2.3.2.1 iframe和embed
- 2.3.2.2 pdfjs
- 2.3.3 docx的预览方案
- 2.3.4 前端预览方案总结
- 2.4 服务端预览方案
- 2.4.1 openOffice
- 2.4.2 kkFileView
- 2.4.3 onlyOffice
1 在线编辑
1.1 PageOffice简介
PageOffice
是一款在线的office
编辑软件,帮助Web应用系统或Web网站实现用户在线编辑Word、Excel、PowerPoint
文档。可以完美实现在线公文流转,领导批阅,盖章。可以给文件添加水印,在线安全预览防止用户下载和复制文件等
1.2 前端项目
由于pageoffice
浏览器是ie
内核,vue3
不兼容ie。所以需要把页面放在后端
1.2.1 配置
在 vue.config.js
中配置代理
devServer: {proxy: {'/api': {target: 'http://localhost:8081/samples-springboot-back', //"/api"对应后端项目"http://localhost:8081/samples-springboot-back"地址 ws: true,changeOrigin: true, // 允许跨域pathRewrite: {'^/api': '' // 标识替换,使用 '/api' 代替真实的接口地址}}}}
1.2.2 页面部分
在index.html
页面引用后端项目(samples-springboot-back
)根目录下的pageoffice.js
<script type="text/javascript" src="http://localhost:8081/samples-springboot-back/pageoffice.js"></script>
在index.vue
页面添加一个按钮,调用POBrowser.openWindowModeless
请求后端。http://localhost:8081/springboot-pageoffice-demo/SimpleWord/Word2
是后端打开文件的controller
POBrowser.openWindowModeless('http://localhost:8081/springboot-pageoffice-demo/SimpleWord/Word2', 'width=1150px;height=900px;');
在Word.vue页面created
中通过axios
请求后台获取pageoffice
控件(注意:后台返回string字符串,前端需要使用v-html
解析)
这里给后台发请求的是axios,如果需要添加token可以在main.js中配置拦截器给请求添加token
Word.vue页面,可以直接复制后修改url
<template><div class="Word"><div style="height: 800px; width: auto" v-html="poHtmlCode" /></div>
</template>
<script>
const axios = require("axios");
export default {name: "Word",data() {return {poHtmlCode: "",};},created: function () {axios.post("/api/SimpleWord/Word").then((response) => {this.poHtmlCode = response.data;}).catch(function (err) {console.log(err);});},methods: {//控件中的一些常用方法都在这里调用,比如保存,打印等等/*** Save()方法是/api/SimpleWord/Word这个后台controller中PageOfficeCtrl控件通过poCtrl.addCustomToolButton定义的方法,除了保存还有另存到本地、打印等功能。*/Save() {document.getElementById("PageOfficeCtrl1").WebSave();}},mounted: function () {// 将PageOffice控件中的方法通过mounted挂载到window对象上,只有挂载后才能被vue组件识别window.Save = this.Save;},
};
</script>
1.3 后端项目
1.3.1 pom.xml
<dependency><groupId>com.zhuozhengsoft</groupId><artifactId>pageoffice</artifactId><version>5.4.0.3</version>
</dependency>
1.3.2 添加配置
在启动类中配置servlet bean
,poSysPath
是在 properites
中配置的磁盘路径(注意
:pageoffice
的poserver.zz
等这些请求不要拦截,get和post请求都放出来)
@Bean
public ServletRegistrationBean pageofficeRegistrationBean() {com.zhuozhengsoft.pageoffice.poserver.Server poserver = new com.zhuozhengsoft.pageoffice.poserver.Server();poserver.setSysPath(poSysPath);//设置PageOffice注册成功后,license.lic文件存放的目录ServletRegistrationBean srb = new ServletRegistrationBean(poserver);srb.addUrlMappings("/poserver.zz");srb.addUrlMappings("/posetup.exe");srb.addUrlMappings("/pageoffice.js");srb.addUrlMappings("/jquery.min.js");srb.addUrlMappings("/pobstyle.css");srb.addUrlMappings("/sealsetup.exe");return srb;
}
1.3.3 controller
打开文件的controller(webopen第一个参数是当前文件的磁盘路径,磁盘路径必须反向双斜杠)。
setServerPage
和setSaveFilePage
中的api是前端代理,前后端分离项目必须配置代理
@RestController
@RequestMapping(value = "/SimpleWord")
public class SimpleWordController { @RequestMapping(value="/Word")public String showWord(HttpServletRequest request) {PageOfficeCtrl poCtrl = new PageOfficeCtrl(request);poCtrl.setServerPage("/api/poserver.zz");//设置服务页面poCtrl.addCustomToolButton("保存", "Save", 1);poCtrl.setSaveFilePage("/api/SimpleWord/save");//设置保存方法的url//打开wordpoCtrl.webOpen("D:\\doc\\test.docx", OpenModeType.docNormalEdit, "张三");return poCtrl.getHtmlCode("PageOfficeCtrl1");}@RequestMapping("save")public void save(HttpServletRequest request, HttpServletResponse response) { FileSaver fs = new FileSaver(request, response);fs.saveToFile("D:\\doc\\" + fs.getFileName());fs.close();} }
2 在线预览
2.1 引言
最近遇到了文件预览的需求,但一搜索发现,这还不是一个简单的功能。于是又去查询了很多资料,调研了一些方案,也踩了好多坑。最后总结方案如下:
- 花钱解决(使用市面上现有的文件预览服务)
微软,google,阿里云 IMM,XDOC,Office Web 365,wps开放平台 - 前端方案
pptx的预览方案,pdf的预览方案,docx的预览方案,xlsx(excel)的预览方案 - 服务端方案
openOffice,kkFileView,onlyOffice
2.2 市面上现有的文件预览服务
2.2.1 微软
docx,pptx,xlsx
可以说是office
三件套,那自然得看一下微软官方提供的文件预览服务。使用方法特别简单,只需要将文件链接,拼接到参数后面即可。
记得encodeURL
https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}
对于docx,pptx,xlsx
都有较好的支持,pdf
不行。
还有一个坑点是:这个服务是否稳定,有什么限制,是否收费,都查不到一个定论。在office官方网站上甚至找不到介绍这个东西的地方。
目前只能找到一个Q&A
:answers.microsoft.com/en-us/msoff…[1]
微软官方人员回答表示:
翻译翻译,就是:几乎永久使用,没有收费计划,不会存储预览的文件数据,限制文件10MB,建议用于 查看互联网上公开的文件。
但经过某些用户测试发现,使用了微软的文件预览服务,然后删除了文件地址,仍然可访问,但过一段时间才会失效。
2.2.2 Google Drive查看器
接入简单,同 Office Web Viewer
,只需要把 src
改为https://drive.google.com/viewer?url=${encodeURIComponent(url)}
即可。
限制25MB,支持以下格式:
测试效果,支持docx,pptx,xlsx,pdf
预览,但pptx
预览的效果不如微软,没有动画效果,样式有小部分会错乱。
2.2.3 阿里云 IMM
官方文档如下:https://help.aliyun.com/zh/imm/?spm=5176.28426678.J_HeJR_wZokYt378dwP-lLl.1.59575181eAvyQZ&scm=20140722.S_help@@文档@@62354.S_BB1@bl+BB2@bl+RQW@ag0+hot+os0.ID_62354-RL_智能媒体管理-LOC_search~UND~helpdoc~UND~item-OR_ser-V_3-P0_0
付费使用
2.2.4 XDOC 文档预览
说了一些大厂的,在介绍一些其他的,需要自行分辨
官网地址:view.xdocin.com/view-xdocin…[3]
2.2.5 Office Web 365
需要注意的是,虽然名字很像office
,但我们看网页的Copyright
可以发现,其实是一个西安的公司,不是微软,但毕竟也提供了文件预览的服务
官网地址:www.officeweb365.com/[4]
2.2.6 WPS开放平台
官方地址:solution.wps.cn/[5]
付费使用,价格如下:
2.3 前端处理方案
2.3.1 pptx的预览方案
先查一下有没有现成的轮子,目前 pptx
的开源预览方案能找到的只有这个:github.com/g21589/PPTX…[6] 。但已经六七年没有更新,也没有维护,笔者使用的时候发现有很多兼容性问题。
简单来说就是,没有。
对于这种情况,我们可以自行解析,主要步骤如下:
- 查询pptx的国际标准
- 解析pptx文件
- 渲染成html或者canvas进行展示
我们先去找一下pptx的国际标准,官方地址:officeopenxml[7]
先解释下什么是officeopenxml:
Office OpenXML
,也称为OpenXML
或OOXML
,是一种基于XML
的办公文档格式,包括文字处理文档、电子表格、演示文稿以及图表、图表、形状和其他图形材料。该规范由微软开发,并于2006年被ECMA国际采用为ECMA-376。第二个版本于2008年12月发布,第三个版本于2011年6月发布。该规范已被ISO和IEC采用为ISO/IEC 29500。
虽然Microsoft继续支持较旧的二进制格式(.doc、.xls和.ppt),但OOXML现在是所有Microsoft Office文档(.docx、.xlsx和.pptx)的默认格式。
由此可见,Office OpenXML由微软开发,目前已经是国际标准。
接下来我们看一下pptx里面有哪些内容,具体可以看pptx的官方标准:officeopenxml-pptx[8]
PresentationML或.pptx文件是一个zip文件,其中包含许多“部分”(通常是UTF-8或UTF-16编码)或XML文件。该包还可能包含其他媒体文件,例如图像。该结构根据 OOXML 标准 ECMA-376 第 2 部分中概述的开放打包约定进行组织。
根据国际标准,我们知道,pptx文件本质就是一个zip文件,其中包含许多部分:
部件的数量和类型将根据演示文稿中的内容而有所不同,但始终会有一个 [Content_Types].xml、一个或多个关系 (.rels) 部件和一个演示文稿部件(演示文稿.xml),它位于 ppt 文件夹中,用于Microsoft Powerpoint 文件。通常,还将至少有一个幻灯片部件,以及一张母版幻灯片和一张版式幻灯片,从中形成幻灯片。
那么js如何读取zip呢?
找到一个工具: www.npmjs.com/package/jsz…[9]
于是我们可以开始尝试解析pptx了。
import JSZip from 'jszip'
// 加载pptx数据
const zip = await JSZip.loadAsync(pptxData)
解析[Content_Types].xml
每个pptx必然会有一个 [Content_Types].xml。此文件包含包中部件的所有内容类型的列表。每个部件及其类型都必须列在 [Content_Types].xml 中。通过它里面的内容,可以解析其他的文件数据
const filesInfo = await getContentTypes(zip)async function getContentTypes(zip: JSZip) {const ContentTypesJson = await readXmlFile(zip, '[Content_Types].xml')const subObj = ContentTypesJson['Types']['Override']const slidesLocArray = []const slideLayoutsLocArray = []for (let i = 0; i < subObj.length; i++) {switch (subObj[i]['attrs']['ContentType']) {case 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml':slidesLocArray.push(subObj[i]['attrs']['PartName'].substr(1))breakcase 'application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml':slideLayoutsLocArray.push(subObj[i]['attrs']['PartName'].substr(1))breakdefault:}}return {slides: slidesLocArray,slideLayouts: slideLayoutsLocArray,}}
解析演示文稿
先获取ppt目录下的presentation.xml演示文稿的大小
由于演示文稿是xml格式,要真正的读取内容需要执行 readXmlFile
const slideSize = await getSlideSize(zip)async function getSlideSize(zip: JSZip) {const content = await readXmlFile(zip, 'ppt/presentation.xml')const sldSzAttrs = content['p:presentation']['p:sldSz']['attrs']return {width: (parseInt(sldSzAttrs['cx']) * 96) / 914400,height: (parseInt(sldSzAttrs['cy']) * 96) / 914400,}}
加载主题
根据 officeopenxml的标准解释
每个包都包含一个关系部件,用于定义其他部件之间的关系以及与包外部资源的关系。这样可以将关系与内容分开,并且可以轻松地更改关系,而无需更改引用目标的源。
除了包的关系部分之外,作为一个或多个关系源的每个部件都有自己的关系部分。每个这样的关系部件都可以在部件的_rels子文件夹中找到,并通过在部件名称后附加“.rels”来命名。
其中主题的相关信息就在ppt/_rels/presentation.xml.rels中
async function loadTheme(zip: JSZip) {const preResContent = await readXmlFile(zip,'ppt/_rels/presentation.xml.rels',)const relationshipArray = preResContent['Relationships']['Relationship']let themeURIif (relationshipArray.constructor === Array) {for (let i = 0; i < relationshipArray.length; i++) {if (relationshipArray[i]['attrs']['Type'] ==='http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme') {themeURI = relationshipArray[i]['attrs']['Target']break}}} else if (relationshipArray['attrs']['Type'] ==='http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme') {themeURI = relationshipArray['attrs']['Target']}if (themeURI === undefined) {throw Error("Can't open theme file.")}return readXmlFile(zip, 'ppt/' + themeURI)}
2.3.2 pdf的预览方案
2.3.2.1 iframe和embed
pdf
比较特别,一般的浏览器默认支持预览pdf。因此,我们可以使用浏览器的能力:<iframe src="viewFileUrl" />
但这样就完全依赖浏览器,对PDF的展示,交互,是否支持全看浏览器的能力,且不同的浏览器展示和交互往往不同,如果需要统一的话,最好还是尝试其他方案。
embed的解析方式也是一样,这里不举例子了
2.3.2.2 pdfjs
npm: www.npmjs.com/package/pdf…[12]
github地址:github.com/mozilla/pdf…[13]
由mozilla出品,就是我们常见的MDN的老大。而且目前 火狐浏览器 使用的 PDF 预览就是采用这个,我们可以用火狐浏览器打开pdf文件,查看浏览器使用的js就能发现
需要注意的是,最新版 pdf.js
限制了 node
版本,需要大于等于18
github链接:github.com/mozilla/pdf…
如果你项目node版本小于这个情况,可能会无法使用。
具体使用情况如下:
import * as pdfjs from 'pdfjs-dist'
import * as pdfjsWorker from 'pdfjs-dist/build/pdf.work.entry'interface Viewport {width: numberheight: numberviewBox: Array<number>
}interface RenderContext {canvasContext: CanvasRenderingContext2D | nulltransform: Array<number>viewport: Viewport
}interface PDFPageProxy {pageNumber: numbergetViewport: () => Viewportrender: (options: RenderContext) => void
}interface PDFDocumentProxy {numPages: numbergetPage: (x: number) => Promise<PDFPageProxy>
}class PdfPreview {private pdfDoc: PDFDocumentProxy | undefinedpageNumber: numbertotal: numberdom: HTMLElementpdf: string | ArrayBufferconstructor(pdf: string | ArrayBuffer, dom: HTMLElement | undefined) {this.pageNumber = 1this.total = 0this.pdfDoc = undefinedthis.pdf = pdfthis.dom = dom ? dom : document.body}private getPdfPage = (number: number) => {return new Promise((resolve, reject) => {if (this.pdfDoc) {this.pdfDoc.getPage(number).then((page: PDFPageProxy) => {const viewport = page.getViewport()const canvas = document.createElement('canvas')this.dom.appendChild(canvas)const context = canvas.getContext('2d')const [_, __, width, height] = viewport.viewBoxcanvas.width = widthcanvas.height = heightviewport.width = widthviewport.height = heightcanvas.style.width = Math.floor(viewport.width) + 'px'canvas.style.height = Math.floor(viewport.height) + 'px'const renderContext = {canvasContext: context,viewport: viewport,transform: [1, 0, 0, -1, 0, viewport.height],}page.render(renderContext)resolve({ success: true, data: page })})} else {reject({ success: false, data: null, message: 'pdfDoc is undefined' })}})}pdfPreview = () => {window.pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorkerwindow.pdfjsLib.getDocument(this.pdf).promise.then(async (doc: PDFDocumentProxy) => {this.pdfDoc = docthis.total = doc.numPagesfor (let i = 1; i <= this.total; i++) {await this.getPdfPage(i)}})}prevPage = () => {if (this.pageNumber > 1) {this.pageNumber -= 1} else {this.pageNumber = 1}this.getPdfPage(this.pageNumber)}nextPage = () => {if (this.pageNumber < this.total) {this.pageNumber += 1} else {this.pageNumber = this.total}this.getPdfPage(this.pageNumber)}
}const createReader = (file: File): Promise<string | ArrayBuffer | null> => {return new Promise((resolve, reject) => {const reader = new FileReader()reader.readAsDataURL(file)reader.onload = () => {resolve(reader.result)}reader.onerror = (error) => {reject(error)}reader.onabort = (abort) => {reject(abort)}})
}export const renderPdf = async (file: File,dom?: HTMLElement,
): Promise<void> => {try {if (typeof window !== 'undefined') {const pdf = await createReader(file)if (pdf) {const PDF = new PdfPreview(pdf, dom)PDF.pdfPreview()}}} catch (error) {console.log('renderPdf', error)}
}
2.3.3 docx的预览方案
我们可以去查看docx的国际标准,去解析文件格式,渲染成html
和canvas
,不过比较好的是,已经有人这么做了,还开源了
使用方法如下:
import { renderAsync } from 'docx-preview'interface DocxOptions {bodyContainer?: HTMLElement | nullstyleContainer?: HTMLElementbuffer: BlobdocxOptions?: Partial<Record<string, string | boolean>>
}export const renderDocx = (options: DocxOptions): Promise<void> | undefined => {if (typeof window !== 'undefined') {const { bodyContainer, styleContainer, buffer, docxOptions = {} } = optionsconst defaultOptions = {className: 'docx',ignoreLastRenderedPageBreak: false,}const configuration = Object.assign({}, defaultOptions, docxOptions)if (bodyContainer) {return renderAsync(buffer, bodyContainer, styleContainer, configuration)} else {const contain = document.createElement('div')document.body.appendChild(contain)return renderAsync(buffer, contain, styleContainer, configuration)}}
}
2.3.4 前端预览方案总结
我们对以上找到的优秀的解决方案,进行改进和总结,并封装成一个web components
组件:preview组件
为什么是web components
组件?
因为它跟框架无关,可以在任何框架中使用,且使用起来跟原生的div标签一样方便。并编写使用文档: preview组件文档, 文档支持交互体验。
目前docx,pdf,xlsx预览基本可以了,都是最好的方案。pptx
预览效果不太好,因为需要自行解析。
2.4 服务端预览方案
2.4.1 openOffice
由于浏览器不能直接打开 docx,pptx,xlsx
等格式文件,但可以直接打开pdf
和图片,因此,我们可以换一个思路,用服务端去转换下文件的格式,转换成浏览器能识别的格式,然后再让浏览器打开,这不就OK了吗,甚至不需要前端处理了。
我们可以借助openOffice
的能力,先介绍一下openOffice
:
Apache OpenOffice
是领先的开源办公软件套件,用于文字处理,电子表格,演示文稿,图形,数据库等。它有多种语言版本,适用于所有常用计算机。它以国际开放标准格式存储您的所有数据,还可以从其他常见的办公软件包中读取和写入文件。它可以出于任何目的完全免费下载和使用。
官网如下:www.openoffice.org
完整示例如下:
package org.example;import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;import java.io.File;public class OfficeUtil {private static OfficeManager officeManager;private static int port[] = {8100};/*** start openOffice service.*/public static void startService() {DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();try {System.out.println("准备启动office转换服务....");configuration.setOfficeHome("这里的路径一般为C:\\Program Files (x86)\\OpenOffice 4的bin目录");configuration.setPortNumbers(port); // 设置转换端口,默认为8100configuration.setTaskExecutionTimeout(1000 * 60 * 30L);// 设置任务执行超时为30分钟configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);// 设置任务队列超时为24小时officeManager = configuration.buildOfficeManager();officeManager.start(); // 启动服务System.out.println("office转换服务启动成功!");} catch (Exception e) {System.out.println("office转换服务启动失败!详细信息:" + e);}}/*** stop openOffice service.*/public static void stopService() {System.out.println("准备关闭office转换服务....");if (officeManager != null) {officeManager.stop();}System.out.println("office转换服务关闭成功!");}public static void convertToPDF(String inputFile, String outputFile) {startService();System.out.println("进行文档转换转换:" + inputFile + " --> " + outputFile);OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);converter.convert(new File(inputFile), new File(outputFile));stopService();}public static void main(String[] args) {convertToPDF("/Users/koolearn/Desktop/asdf.docx", "/Users/koolearn/Desktop/adsf.pdf");}
}
2.4.2 kkFileView
支持的文件预览格式非常丰富图片
安装下libreoffice :
kkFileView明确要求的额外依赖 libreoffice
,否则无法启动
启动项目
找到主文件,主函数mian,即可执行
2.4.3 onlyOffice
官网地址:https://www.onlyoffice.com/zh
开发者版本和社区版免费,企业版付费:www.onlyoffice.com/zh/docs-ent
预览的文件种类没有kkFileView
多,但对office
三件套有很好的支持,甚至支持多人编辑。
相关文章:

Java实现在线编辑预览office文档
文章目录 1 在线编辑1.1 PageOffice简介1.2 前端项目1.2.1 配置1.2.2 页面部分 1.3 后端项目1.3.1 pom.xml1.3.2 添加配置1.3.3 controller 2 在线预览2.1 引言2.2 市面上现有的文件预览服务2.2.1 微软2.2.2 Google Drive查看器2.2.3 阿里云 IMM2.2.4 XDOC 文档预览2.2.5 Offic…...

阿里云OSS上传视频,可分片上传
uniappH5实现 阿里云OSS上传视频 示例图: 上传视频完整示例代码: 使用npm安装SDK开发包,安装命令为 npm install ali-oss --save accessKeyId 和 accessKeySecret 还有 bucket 替换成你的就行。 multipartUpload 的第一个入参是&#x…...
Linux第三次课后作业
1.使用while和until语句编写脚本程序,计算1到100的和。 i1 s0 while(i<100) {sii} echo(s)sum0 i0 until test $num -eq 101 do #下面两个均为反斜杠 sumexpr $sum $i iexpr $num 1 done echo "the result is $sum"2.编写脚本程序备份用户指定的文件…...

WordPress后台仪表盘自定义添加删除概览项目插件Glance That
成功搭建WordPress站点,登录后台后可以在“仪表盘 – 概览”中看到包括多少篇文章、多少个页面、多少条评论和当前WordPress版本号及所使用的主题。具体如下图所示: 但是如果我们的WordPress站点还有自定义文章类型,也想在概览中显示出来应该…...

.Net6使用SignalR实现前后端实时通信
代码部分 后端代码 (Asp.net core web api,用的.net6)Program.cs 代码运行逻辑: 1. 通过 WebApplication.CreateBuilder(args) 创建一个 ASP.NET Core 应用程序建造器。 2. 使用 builder.Services.AddControllers() 添加 MVC 控…...

基于SpringBoot+Vue的时装服饰商城购物系统
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...

近4w字吐血整理!只要你认真看完【C++编程核心知识】分分钟吊打面试官(包含:内存、函数、引用、类与对象、文件操作)
🌈个人主页:godspeed_lucip 🔥 系列专栏:C从基础到进阶 🏆🏆关注博主,随时获取更多关于C的优质内容!🏆🏆 C核心编程🌏1 内存分区模型🎄…...

pytest学习和使用-pytest如何进行分布式测试?(pytest-xdist)
1 什么是分布式测试? 在进行本文之前,先了解些基础知识,什么是分布式测试?分布式测试:是指通过局域网和Internet,把分布于不同地点、独立完成特定功能的测试计算机连接起来,以达到测试资源共享…...

虚拟ip可以解决所有的安全问题吗
虚拟IP(Virtual IP)是一种网络技术,可以把多台物理服务器或设备组合成一个逻辑集群,并且使用同一个IP地址对外提供服务。虚拟IP具有负载均衡、故障切换和高可用性等优势,同时还可以作为一种安全措施来增加系统的抗攻击…...

【数据库原理】(27)数据库恢复
在数据库系统中,恢复是指在发生某种故障导致数据库数据不再正确时,将数据库恢复到已知正确的某一状态的过程。数据库故障可能由多种原因引起,包括硬件故障、软件错误、操作员失误以及恶意破坏。为了确保数据库的安全性和完整性,数…...
施工企业工程管理信息化、智能化需求分析
一、引言 随着科技的飞速发展,信息化、智能化技术正在逐步改变各行各业的工作方式。对于施工企业而言,传统的工程管理方式已难以满足现代工程项目的复杂需求。为了提高效率、降低成本并确保工程的安全与质量,施工企业工程管理迫切需要进入信…...

Centos7 安装与卸载mysql
卸载 ps ajx | grep mysql : 查看当前服务器是否有mysql 没有的话就不需要卸载咯。 centos7 通过yum下载安装包通常是以.rpm为后缀,rpm -qa 可以查看当前服务器上所有的安装包: rpm -qa | grep mysql | xargs yum -y remove :将查询到的mysql…...

ASP.NET Core 的 Web Api 实现限流 中间件
Microsoft.AspNetCore.RateLimiting 中间件提供速率限制(限流)中间件。 它是.NET 7 以上版本才支持的中间件,刚看了一下,确实挺好用,下面给大家简单介绍一下: RateLimiterOptionsExtensions 类提供下列用…...
Mysql字段的各种时间类型
DATE: 特点:存储日期,不包含时间。示例: CREATE TABLE example_date (id INT PRIMARY KEY, event_date DATE ); INSERT INTO example_date (id, event_date) VALUES (1, 2023-01-11); TIME: 特点:存储时间,不包含日…...

Armv8-R AArch32 architecture概念学习
提示 该博客主要为个人学习,通过阅读官网手册整理而来(个人觉得阅读官网的英文文档非常有助于理解各个IP特性)。若有不对之处请参考参考文档,以官网文档为准。阅读该文章,可以先查看AArch64 Exception Model学习&…...

linux手动安装 vscode-server
适用场景 很多时候,我们需要在本机(比如windows)通过remote ssh访问远程服务器(一般是ubuntu),但经常出现 vscode 一直连不上远程服务器的情况,看一下 log: 这个log表示远程服务器…...

【Maven】009-Maven 简单父子工程搭建
【Maven】009-Maven 简单父子工程搭建 文章目录 【Maven】009-Maven 简单父子工程搭建一、需求说明1、结构2、第三方库 二、工程搭建1、父工程第一步:创建父工程第二步:引入公共依赖 lombok 和管理 hutool 依赖版本 2、公共子模块第一步:创建…...

verilog编程题
verilog编程题 文章目录 verilog编程题序列检测电路(状态机实现)分频电路计数器译码器选择器加减器触发器寄存器 序列检测电路(状态机实现) module Detect_101(input clk,input rst_n,input data,o…...

What is `addArgumentResolvers` does in `WebMvcConfigurer` ?
addArgumentResolvers 在SpringMVC框架中,主要用于向Spring容器注册自定义的参数解析器。在处理HTTP请求时,SpringMVC会使用这些参数解析器将请求中的数据(如查询参数、路径变量、表单数据等)转换并注入到控制器方法的参数中。 使…...

[NSSCTF Round#16 Basic]RCE但是没有完全RCE
RCE但是没有完全RCE wp 题目代码: 第一关 <?php error_reporting(0); highlight_file(__file__); include(level2.php); if (isset($_GET[md5_1]) && isset($_GET[md5_2])) {if ((string)$_GET[md5_1] ! (string)$_GET[md5_2] && md5($_GET[m…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...