poi-excel-添加水印

1、官网快速指南

https://poi.apache.org/components/spreadsheet/quick-guide.html
访问如上地址可以查看到poi的相关操作方式:

  • How to create a new workbook
  • How to create a sheet
  • How to create cells
  • How to create date cells
  • Working with different types of cells
  • Iterate over rows and cells
  • Getting the cell contents
  • Text Extraction
  • Files vs InputStreams
  • Aligning cells
  • Working with borders
  • Fills and color
  • Merging cells
  • Working with fonts
  • ......

https://archive.apache.org/dist/poi/release/src/

https://archive.apache.org/dist/poi/release/bin/

2、如何处理水印

在excel中没有水印的概念,只能通过其他形式视觉上达到水印的效果;
方式一:可以通过页眉页脚的方式:
        优点:全文覆盖、打印预览可查看  缺点:无法编辑、在非打印预览视图下无法查看
方式二:插入图片方式
        优点:在非打印预览视图下可以查看  缺点:打印的时候无法展示

3、实现方式

3.1、页眉页脚实现方式

3.1.1 pom依赖

<!-- Apache POI 核心库 -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version>
</dependency><!-- OOXML 模式库(提供 CTLocking 等类) -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-lite</artifactId><version>5.2.3</version>
</dependency>

3.1.2 简单代码

  public static void buildHeaderAndFooter () throws IOException {// 创建文档Workbook wb = new HSSFWorkbook();// 创建sheet页Sheet sheet = wb.createSheet("sheet名称");// 创建行Row row = sheet.createRow(0);// 创建列Cell cell = row.createCell(0);// 设置单元格内容cell.setCellValue("测试测试");// 获取页眉Header header = sheet.getHeader();// 设置页眉header.setCenter("&\"微软雅黑,Bold\"&14&KAAAAAA 公司机密 - 严禁外传 - 页眉");sheet.setMargin(Sheet.HeaderMargin, 0.8);// 获取页脚Footer footer = sheet.getFooter();// 设置页脚footer.setCenter("&\"微软雅黑,Bold\"&14&KAAAAAA 公司机密 - 严禁外传 - 页脚");sheet.setMargin(Sheet.FooterMargin, 0.8);// TODO 需要根据自己的本地地址修改try (OutputStream fileOut = new FileOutputStream("D://workbook.xls")) {wb.write(fileOut);}}

3.1.3 效果

普通视图下: 没有任何效果

 预览模式下:页眉页脚展示咱们得水印

 3.2 背景图片实现方式

3.2.1 pom依赖

<!-- Apache POI 核心库 -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version>
</dependency><!-- OOXML 模式库(提供 CTLocking 等类) -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-lite</artifactId><version>5.2.3</version>
</dependency>

3.2.2 简单代码

 public static void picture() throws IOException{// 创建文档Workbook wb = new XSSFWorkbook();// 背景图片的位置 TODO 需要修改成本地地址InputStream is = new FileInputStream("D://a.png");byte[] bytes = IOUtils.toByteArray(is);// 设置成背景图片int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);is.close();CreationHelper helper = wb.getCreationHelper();// 创建sheet页Sheet sheet = wb.createSheet();// 创建绘图容器(drawing patriarch)这是 Excel 中所有形状(包括图片)的顶级容器。每个 sheet 只能有一个绘图容器。Drawing drawing = sheet.createDrawingPatriarch();// 创建锚点(ClientAnchor)对象。锚点用于确定图片在 sheet 中的位置和大小ClientAnchor anchor = helper.createClientAnchor();// 设置起始列(从0开始计数)anchor.setCol1(3);// 设置起始行(从0开始计数)anchor.setRow1(2);Picture pict = drawing.createPicture(anchor, pictureIdx);// 根据图片原始尺寸自动调整显示大小pict.resize();// 保存excel文件地址,TODO 需根据本地地址调整String file = "D://picture.xls";if (wb instanceof XSSFWorkbook) file += "x";try (OutputStream fileOut = new FileOutputStream(file)) {wb.write(fileOut);}}

3.2.3 效果

不足之处在于添加的背景图片可以被删除,这样水印就没啥意义了

3.2.4 针对水印可被删除的改进方式

代码调整

 public static void buildPicture() throws IOException{// 创建文档XSSFWorkbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();// 背景图片的位置 TODO 需要修改成本地地址InputStream is = new FileInputStream("D://a.png");byte[] bytes = IOUtils.toByteArray(is);// 添加图片到工作簿int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);//  返回工作簿中所有图片的列表POIXMLDocumentPart poixmlDocumentPart = wb.getAllPictures().get(pictureIdx);CreationHelper helper = wb.getCreationHelper();// 创建sheet页XSSFSheet sheet = wb.createSheet();/*** getPackagePart() 获取图片在 OOXML 包中的物理表示(即 ZIP 包中的一个文件)。* getPartName() 返回该文件的路径(如 /xl/media/image1.png)。*/PackagePartName ppn = poixmlDocumentPart.getPackagePart().getPartName();String relType = XSSFRelation.IMAGES.getRelation();PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);// 设置图片为工作表背景sheet.getCTWorksheet().addNewPicture().setId(pr.getId());String file = "D://picture.xls";if (wb instanceof XSSFWorkbook) file += "x";try (OutputStream fileOut = new FileOutputStream(file)) {wb.write(fileOut);}is.close();}

 效果如下: 水印无法选中也无法删除

 4、完整示例

主要是使用背景图片的方式来实现excel的水印效果

4.1、pom依赖

<!-- Apache POI 核心库 -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version>
</dependency><!-- OOXML 模式库(提供 CTLocking 等类) -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-lite</artifactId><version>5.2.3</version>
</dependency>

 4.2、代码

package water1;import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Font;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;public class ExcelWatermarkGenerator {public static void main(String[] args) {try {String outputFile = "D://平铺水印数据表.xlsx";createTiledWatermarkExcel(outputFile);System.out.println("成功创建带平铺水印的Excel文件: " + new File(outputFile).getAbsolutePath());} catch (Exception e) {System.err.println("创建Excel文件时出错: " + e.getMessage());e.printStackTrace();}}public static void createTiledWatermarkExcel(String outputPath) throws Exception {// 1. 创建工作簿XSSFWorkbook workbook = new XSSFWorkbook();XSSFSheet sheet = (XSSFSheet)workbook.createSheet("销售数据");// 2. 添加标题行addTitleRow(sheet);// 3. 添加示例数据addSampleData(sheet);// 4. 设置列宽setColumnWidths(sheet);// 5. 创建平铺水印图片 TODO  “公司机密” 可替换成需要的水印文字byte[] watermarkImage = createTiledWatermarkImage("公司机密", 4, 3); // 4列3行平铺// 6. 添加水印到ExceladdWatermarkToSheet(workbook, sheet, watermarkImage);// 7. 添加WPS兼容的页眉文本水印addHeaderWatermarkForWPS(sheet);// 8. 设置打印选项setupPrintSettings(sheet);// 9. 保存文件try (FileOutputStream out = new FileOutputStream(outputPath)) {workbook.write(out);}workbook.close();}private static void addTitleRow(Sheet sheet) {Row titleRow = sheet.createRow(0);titleRow.setHeightInPoints(25);CellStyle titleStyle = createTitleStyle(sheet.getWorkbook());String[] titles = {"产品名称", "生产日期", "库存数量", "单价(元)", "总价值"};for (int i = 0; i < titles.length; i++) {Cell cell = titleRow.createCell(i);cell.setCellValue(titles[i]);cell.setCellStyle(titleStyle);}}private static CellStyle createTitleStyle(Workbook workbook) {CellStyle style = workbook.createCellStyle();style.setFillForegroundColor(IndexedColors.ROYAL_BLUE.getIndex());style.setFillPattern(FillPatternType.SOLID_FOREGROUND);org.apache.poi.ss.usermodel.Font font = workbook.createFont();font.setBold(true);font.setFontHeightInPoints((short) 12);font.setColor(IndexedColors.WHITE.getIndex());style.setFont(font);style.setBorderTop(BorderStyle.THIN);style.setBorderBottom(BorderStyle.THIN);style.setBorderLeft(BorderStyle.THIN);style.setBorderRight(BorderStyle.THIN);style.setTopBorderColor(IndexedColors.BLUE.getIndex());style.setAlignment(HorizontalAlignment.CENTER);style.setVerticalAlignment(VerticalAlignment.CENTER);return style;}private static void addSampleData(Sheet sheet) {CellStyle dateStyle = createDateStyle(sheet.getWorkbook());CellStyle currencyStyle = createCurrencyStyle(sheet.getWorkbook());String[] products = {"智能手机", "笔记本电脑", "平板电脑", "智能手表", "蓝牙耳机"};SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");for (int i = 1; i <= 30; i++) {Row row = sheet.createRow(i);// 产品名称row.createCell(0).setCellValue(products[i % products.length] + " " + (i % 5 + 1) + "代");// 生产日期Cell dateCell = row.createCell(1);Date date = new Date(System.currentTimeMillis() - (i * 24 * 60 * 60 * 1000L));dateCell.setCellValue(date);dateCell.setCellStyle(dateStyle);// 库存数量row.createCell(2).setCellValue(100 + (int)(Math.random() * 500));// 单价Cell priceCell = row.createCell(3);double price = 500 + (Math.random() * 3000);priceCell.setCellValue(price);priceCell.setCellStyle(currencyStyle);// 总价值(公式计算)Cell valueCell = row.createCell(4);valueCell.setCellFormula("C" + (i+1) + "*D" + (i+1));valueCell.setCellStyle(currencyStyle);}}private static CellStyle createDateStyle(Workbook workbook) {CellStyle style = workbook.createCellStyle();style.setLocked(false); // 允许编辑CreationHelper createHelper = workbook.getCreationHelper();style.setDataFormat(createHelper.createDataFormat().getFormat("yyyy-mm-dd"));return style;}private static CellStyle createCurrencyStyle(Workbook workbook) {CellStyle style = workbook.createCellStyle();style.setLocked(false); // 允许编辑style.setDataFormat((short) BuiltinFormats.getBuiltinFormat("¥#,##0.00"));return style;}private static void setColumnWidths(Sheet sheet) {sheet.setColumnWidth(0, 25 * 256);  // 产品名称sheet.setColumnWidth(1, 15 * 256);  // 生产日期sheet.setColumnWidth(2, 12 * 256);  // 库存数量sheet.setColumnWidth(3, 12 * 256);  // 单价sheet.setColumnWidth(4, 15 * 256);  // 总价值}private static byte[] createTiledWatermarkImage(String text, int cols, int rows) throws IOException {// 1. 设置单个水印单元尺寸int cellWidth = 300;int cellHeight = 200;// 2. 计算总图片尺寸int totalWidth = cellWidth * cols;int totalHeight = cellHeight * rows;// 3. 创建透明背景图片BufferedImage image = new BufferedImage(totalWidth, totalHeight, BufferedImage.TYPE_INT_ARGB);Graphics2D g2d = image.createGraphics();// 4. 设置透明背景g2d.setComposite(AlphaComposite.Clear);g2d.fillRect(0, 0, totalWidth, totalHeight);g2d.setComposite(AlphaComposite.Src);// 5. 设置水印样式g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);g2d.setColor(new Color(180, 180, 180, 50)); // 半透明灰色// 6. 使用WPS兼容字体Font font = new Font("微软雅黑", Font.BOLD, 36);g2d.setFont(font);// 7. 在网格中平铺水印for (int row = 0; row < rows; row++) {for (int col = 0; col < cols; col++) {// 计算当前单元中心位置int centerX = col * cellWidth + cellWidth / 2;int centerY = row * cellHeight + cellHeight / 2;// 保存当前变换AffineTransform originalTransform = g2d.getTransform();// 移动到当前单元中心g2d.translate(centerX, centerY);// 旋转文本g2d.rotate(Math.toRadians(-30));// 计算文本位置(居中)FontMetrics metrics = g2d.getFontMetrics();int textWidth = metrics.stringWidth(text);int x = -textWidth / 2;int y = metrics.getHeight() / 4;// 绘制水印文本g2d.drawString(text, x, y);// 恢复原始变换g2d.setTransform(originalTransform);}}g2d.dispose();// 8. 将图片转换为字节数组ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(image, "PNG", baos);return baos.toByteArray();}private static void addWatermarkToSheet(XSSFWorkbook workbook, XSSFSheet sheet, byte[] watermarkImage) throws Exception {// 1. 添加图片到工作簿int pictureIdx = workbook.addPicture(watermarkImage, Workbook.PICTURE_TYPE_PNG);//  返回工作簿中所有图片的列表POIXMLDocumentPart poixmlDocumentPart = workbook.getAllPictures().get(pictureIdx);CreationHelper helper = workbook.getCreationHelper();/*** getPackagePart() 获取图片在 OOXML 包中的物理表示(即 ZIP 包中的一个文件)。* getPartName() 返回该文件的路径(如 /xl/media/image1.png)。*/PackagePartName ppn = poixmlDocumentPart.getPackagePart().getPartName();String relType = XSSFRelation.IMAGES.getRelation();PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);// 设置图片为工作表背景sheet.getCTWorksheet().addNewPicture().setId(pr.getId());}private static void addHeaderWatermarkForWPS(Sheet sheet) {// WPS兼容性:添加文本水印到页眉Header header = sheet.getHeader();header.setCenter("&\"微软雅黑,Bold\"&14&KAAAAAA 公司机密 - 严禁外传");sheet.setMargin(Sheet.HeaderMargin, 0.8);}private static void setupPrintSettings(Sheet sheet) {// 1. 设置页面为横向sheet.getPrintSetup().setLandscape(true);// 2. 设置页边距sheet.setMargin(Sheet.TopMargin, 0.7);sheet.setMargin(Sheet.BottomMargin, 0.7);sheet.setMargin(Sheet.LeftMargin, 0.5);sheet.setMargin(Sheet.RightMargin, 0.5);// 3. 设置打印标题行sheet.setRepeatingRows(CellRangeAddress.valueOf("1:1"));// 4. 设置网格线sheet.setDisplayGridlines(true);sheet.setPrintGridlines(true);// 5. 设置缩放比例sheet.setZoom(90); // 90%缩放}
}

 4.3 效果


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/90039.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/90039.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 开发的鼠标:技术详解与实现指南

概述基于STM32微控制器开发的鼠标是一种高度可定化的输入设备解决方案&#xff0c;广泛应用于工业控制、嵌入式系统、特殊人机交互等领域。相比传统鼠标&#xff0c;STM32鼠标具有以下优势&#xff1a;高度可定制性&#xff1a;可添加特殊功能按键、传感器集成低功耗设计&#…

GoLang教程007:打印空心金字塔

4.6 案例一&#xff1a;打印金字塔编写一个程序&#xff0c;可以接收一个整数&#xff0c;表示层数&#xff0c;打印出金字塔。1️⃣第一步&#xff1a;打印一个矩形 package mainimport "fmt"func main() {// i表示层数for i : 1; i < 3; i {// j表示每层打印多少…

iOS开发 Swift 速记3:运算符与控制结构

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

ElasticSearch中需要注意的点,附官方文档解读

1.批量更新数量大小限制 https://www.elastic.co/guide/cn/elasticsearch/guide/current/bulk.html#_How_Big_Is_Too_Big 整个批量请求都需要由接收到请求的节点加载到内存中&#xff0c;因此该请求越大&#xff0c;其他请求所能获得的内存就越少。批量请求的大小有一个最佳值…

Git GitHub精通:前端协作开发的“瑞士军刀“!

前言&#xff1a;为什么你的代码总是"失踪"&#xff1f; "啊&#xff01;我的代码呢&#xff1f;"——这可能是每个程序员都曾发出过的灵魂呐喊。还记得上周我熬夜写的300行JavaScript&#xff0c;第二天醒来发现被自己手贱覆盖了&#xff0c;那一刻我深刻…

第 30 场 蓝桥·算法入门赛 题解

1. 零食争议【算法赛】 签到题&#xff1a;1-7奇数相加 #include <bits/stdc.h> using namespace std; int main() {// 请在此输入您的代码cout<<1357;return 0; } 2. 数字炸弹【算法赛】 把n个人看为前n-1和后n-1 &#xff0c; 方便找到是第几段的第几个数 #in…

闲庭信步使用图像验证平台加速FPGA的开发:第二十四课——图像直方图均衡化的FPGA实现

&#xff08;本系列只需要modelsim即可完成数字图像的处理&#xff0c;每个工程都搭建了全自动化的仿真环境&#xff0c;只需要双击top_tb.bat文件就可以完成整个的仿真&#xff0c;大大降低了初学者的门槛&#xff01;&#xff01;&#xff01;&#xff01;如需要该系列的工程…

LabVIEW 2025安装包| 免费免激活版下载| 附图文详细安装教程

[软件名称]&#xff1a;LabVIEW 2025 [软件大小]&#xff1a;13 G [系统要求]&#xff1a;支持Win7及更高版本 [下载通道]:夸克网盘 [下载链接]: https://pan.quark.cn/s/7e9527cc06a3 &#xff08;建议用手机保存到网盘后&#xff0c;再用电脑下载&#xff09; 更多免费软件&a…

如何实现泵站的无人值守:御控智慧水务平台

在城乡供水、农田灌溉、工业循环水等场景中&#xff0c;泵站作为核心动力设施&#xff0c;其运行效率直接影响水资源调配的稳定性。然而&#xff0c;传统泵站管理长期面临三大痛点&#xff1a;人力成本高昂&#xff1a;偏远地区泵站需24小时值守&#xff0c;单站年均人力成本超…

深度学习篇---车道线循迹

要实现基于深度学习的双车道线&#xff08;黄色车道线&#xff09;循迹&#xff08;通过预测四个轮子的转速实现自主控制&#xff09;&#xff0c;需要从数据采集、模型设计、训练策略、环境适应等多维度系统优化。以下是具体方案及需要注意的关键事项&#xff0c;旨在提升精准…

JavaScript,发生异常,try...catch...finally处理,继续向上层调用者传递异常信息

JavaScript中&#xff0c;‌异常&#xff08;Exception&#xff09;和错误&#xff08;Error&#xff09; JavaScript 是一种解释型语言&#xff0c;通常在浏览器中通过JavaScript引擎执行。最著名的两个引擎是&#xff1a;SpiderMonkey&#xff08;由 Mozilla Firefox 使用&a…

SpringMVC快速入门之启动配置流程

SpringMVC快速入门之启动配置流程一、SpringMVC启动的核心流程二、环境准备与依赖配置2.1 开发环境2.2 Maven依赖配置三、初始化Servlet容器&#xff1a;WebApplicationInitializer3.1 实现WebApplicationInitializer3.2 配置编码过滤器&#xff08;解决中文乱码&#xff09;四…

ArcGIS水文及空间分析与SWMM融合协同在城市排水防涝领域中的应用

随着计算机的广泛应用和各类模型软件的发展&#xff0c;将排水系统模型作为城市洪灾评价与防治的技术手段已经成为防洪防灾的重要技术途径。将创新性融合地理信息系统&#xff08;GIS&#xff09;的空间分析能力与暴雨雨水管理模型&#xff08;SWMM&#xff09;的水动力计算优势…

PHICOMM(斐讯)N1盒子 - Armbian25.05(Debian 12)刷入U盘/EMMC

PHICOMM(斐讯)N1盒子 - Armbian25.05(Debian 12)刷入U盘/EMMC 文章目录PHICOMM(斐讯)N1盒子 - Armbian25.05(Debian 12)刷入U盘/EMMC前言1. 确保固件版本为2.192. 刷系统到U盘3. 启动U盘系统4. U盘系统写入EMMC5. 关机拨U盘6. 重新上电环境&#xff1a; 系统&#xff1a;Armbi…

《计算机网络基础知识全解析:从协议模型到通信实践》

《计算机网络基础知识全解析&#xff1a;从协议模型到通信实践》 在数字化时代&#xff0c;计算机网络是信息传递的基石&#xff0c;从日常浏览网页到企业数据交互&#xff0c;都离不开网络协议的规范与支撑。本文将系统梳理计算机网络的核心知识&#xff0c;从通信模型到具体协…

【补题】Codeforces Global Round 26 E. Shuffle

题意&#xff1a;给出一棵树&#xff0c;按照以下方式操作 对于当前的所有任意子树&#xff0c;选出任何一个点从中删除&#xff0c;然后作为新子树的根插入到新的树中&#xff0c;以此递归往复&#xff0c;直到原来的树中节点全部进入新树&#xff0c;问新树最多有多少个叶子节…

金仓数据库风云

O 记我用了这么多年&#xff0c;我最有发言权&#xff0c;我可不敢替&#xff0c;你们谁能搞定&#xff0c;谁上。” 老邓在会上&#xff0c;狠狠甩了一句气话。老邓&#xff08;邓铭&#xff09;&#xff0c;某大型期货交易所信息化主管&#xff0c;数据库老司机。 作为圈里最…

阿里云宝塔Linux面板相关操作记录

1、清空nginx缓存使用Nginx时&#xff0c;静态图片文件会出现缓存&#xff0c;所以需要清空缓存&#xff0c;方法如下&#xff1a;sudo rm -rf /www/server/nginx/proxy_cache_dir/*2、Windows启动spring boot jar脚本echo off setlocal enabledelayedexpansion:: 配置项目名 s…

Kotlin伴生对象

你已经知道如何为类创建单例对象&#xff08;singleton&#xff09;。不过&#xff0c;在很多情况下&#xff0c;你只需要为某个类维护一个单例&#xff0c;这时候使用类的完整名字会显得冗长。比如&#xff0c;你可能只需要存储一个公共的属性。这种情况下&#xff0c;可以用 …

4G车载录像机的作用详解:提升行车安全与智能管理的核心技术

1. 引言随着物流运输、公共交通、特种车辆等行业对安全与管理需求的提升&#xff0c;4G车载录像机已成为现代车辆智能化管理的重要组成部分。它不仅具备传统行车记录仪的录像功能&#xff0c;还结合4G无线通信、AI智能分析、GPS定位、云存储等技术&#xff0c;实现远程监控、实…