Uniapp如何驱动JLP352蓝牙热敏打印机:从BLE连接到位图打印的完整实践
1. 场景与架构Uniapp、hiprint、JLP352到底怎么分工先说结论这个需求的本质不是“在Uniapp里跑hiprint”而是“用Uniapp的蓝牙能力驱动JLP352这台蓝牙热敏打印机把内容打印出来”。hiprint在里面扮演的角色是Web端的排版和模板设计而不是连接打印机的那一环。想清楚这一点后面就不会被带偏。我是在一个门店收银和配送项目里遇到这个需求的。前端管理后台用的是Vue打印小票、电子面单用的hiprint排版效果挺好。后来业务要扩展到移动端店员拿着手机就能直接开单、直接打印设备选型定了济强JLP352。问题就来了Uniapp封装好了跨端的蓝牙API但hiprint本身依赖DOM和浏览器打印机制在Uniapp的App端没法直接用。我们要解决的就是“如何在Uniapp里完成从内容排版、数据转换到蓝牙发送的整条链路”。整套方案我会拆成三层来看排版层负责把文本、图片、二维码摆放到一张小票/面单上。在PC端用hiprint做模板在移动端用Canvas画同样的布局。数据层把排版结果变成打印机认得的字节流。JLP352这类热敏打印机普遍支持ESC/POS指令最省事的做法是把内容渲染成位图再转成点阵数据。传输层通过Uniapp的BLE API连接打印机分包写入这些字节流。这三层分清楚之后你会发现每一层都有对应的成熟做法难点其实集中在数据层的点阵转换和传输层的分包策略上。这两个地方做好了整个打印体验基本就稳了。2. 摸清JLP352的设备底细2.1 这类便携热敏打印机的工作方式JLP352是一台便携式蓝牙热敏打印机内部核心机制和市面上大多数58mm热敏小票机一致。它接收的指令是ESC/POS指令集通过蓝牙通道把指令字节流传给打印机打印机解析后控制热敏头加热在热敏纸上“烧”出内容。纸宽通常是58mm可打印宽度大约48mm。在203dpi分辨率下48mm对应384个点一行像素刚好48个字节。这个“384点/48字节”很关键。后续做图片转点阵时所有宽度计算都会围绕它展开。如果你的机型可打印宽度不是48mm按实际参数换算即可宽度点数 打印宽度(mm) × 8203dpi下每毫米约8个点。2.2 连接协议BLE还是SPP蓝牙打印机有两种常见连接方式传统蓝牙SPP和低功耗蓝牙BLE。SPP在Android上支持得很早但iOS不支持原生SPPBLE则是目前所有Uniapp蓝牙API的默认目标。JLP352据我了解支持BLE所以Uniapp的uni.openBluetoothAdapter那一套API可以直接使用。如果你拿到的设备只支持SPPUniapp内置API是搞不定的需要找原生插件或者通过厂商提供的SDK封装成Uniapp插件。所以拿到设备后第一件事不是写代码而是确认它到底走BLE还是SPP。用手机厂商的蓝牙调试工具扫一下看能不能搜到并且能读到服务列表基本就能判断。2.3 指令集与打印参数ESC/POS指令是一串十六进制字节常用的有那么几条功能指令字节初始化ESC 1B 40打印位图GS v 01D 76 30 00 xL xH yL yH 数据...走纸换行LF0A走纸n点ESC J n1B 4A n设置对齐ESC a n1B 61 n初看觉得简单但实际项目里文本指令会有编码问题。JLP352对中文通常支持GBK编码而Uniapp里到处是UTF-8直接字符串转字节发送中文很容易乱码。这也是我推荐“图片化打印”的核心原因把中文、二维码、排版统统画进Canvas转成点阵后用GS v 0打印绕开编码问题。3. Uniapp蓝牙核心链路从扫描到写入3.1 扫描与连接Uniapp的蓝牙API和微信小程序的蓝牙API基本一致App端也做了兼容。整个流程是初始化蓝牙 - 扫描设备 - 停止扫描 - 连接设备 - 发现服务 - 发现特征值 - 写入数据。先看初始化和扫描这段// 初始化蓝牙适配器 uni.openBluetoothAdapter({ success: () { // 开始扫描 uni.startBluetoothDevicesDiscovery({ allowDuplicatesKey: false, success: () { console.log(正在搜索蓝牙设备) } }) }, fail: (err) { console.error(蓝牙初始化失败, err) } })关键点在uni.onBluetoothDeviceFound回调里过滤设备。JLP352广播出来的设备名一般会包含“JLP352”几个字或者你可以在设备背面找到厂家默认名称。uni.onBluetoothDeviceFound((res) { const devices res.devices || [] devices.forEach((device) { const name device.name || device.localName || if (name.indexOf(JLP352) -1 || name.indexOf(JL) -1) { // 找到了目标打印机停止扫描并连接 uni.stopBluetoothDevicesDiscovery({}) connectDevice(device.deviceId) } }) })这里注意一个坑Android上搜索蓝牙设备必须开启定位权限否则onBluetoothDeviceFound永远不回调。iOS上首次使用蓝牙会弹系统授权框要在App里提前处理拒绝的情况。3.2 找到服务和可写特征值连接成功后要走服务发现和特征值发现。打印机的BLE服务往往用的是自定义UUID不能靠名字猜必须遍历服务和特征值找到properties.write为 true 的那个特征值它就是我们的数据通道。function connectDevice(deviceId) { uni.createBLEConnection({ deviceId, success: () { uni.getBLEDeviceServices({ deviceId, success: (res) { const services res.services // 遍历服务 services.forEach((service) { uni.getBLEDeviceCharacteristics({ deviceId, serviceId: service.uuid, success: (res) { const characteristics res.characteristics characteristics.forEach((char) { if (char.properties.write) { // 记住这个可写特征值 this.writeServiceId service.uuid this.writeCharId char.uuid } }) } }) }) } }) } }) }现实里很多打印机会暴露多个服务如果你按上面代码遍历可能会找到不止一个可写特征值。有的特征是用于发数据的有的可能是用于配置的。稳妥的做法是先打印出所有服务和特征值UUID对照设备文档确认哪个是打印机的主通道。大多时候服务UUID形如FF00特征值形如FF02但也不要盲信。3.3 分包发送与发送队列BLE的MTU限制是所有蓝牙打印方案的共性问题。默认MTU一般是23字节扣除3字节协议开销单次写入实际只有20字节。而一张384点宽的热敏图片一行48字节一屏下来动辄几千字节。不分包数据根本发不出去。所以写入必须分包而且要控制节奏。我常用的实现是“队列发送”const MAX_CHUNK_SIZE 20 function sendDataToPrinter(byteArray, onComplete, onError) { let offset 0 function writeNext() { if (offset byteArray.length) { onComplete onComplete() return } const end Math.min(offset MAX_CHUNK_SIZE, byteArray.length) const chunk byteArray.slice(offset, end) const buffer new ArrayBuffer(chunk.length) const view new Uint8Array(buffer) view.set(chunk) uni.writeBLECharacteristicValue({ deviceId: this.deviceId, serviceId: this.writeServiceId, characteristicId: this.writeCharId, value: buffer, success: () { offset end // 必须等待上一次写入完成后再发下一次 setTimeout(writeNext, 30) }, fail: (err) { onError onError(err) } }) } writeNext() }几个心得分包大小最保险是20字节。虽然Android上可以通过协商MTU提升到247字节但iOS上系统不会让你为外设协商MTU所以按20字节走最稳。每个包之间要留时间间隔我建议30ms以上。有些打印机内部处理跟不上发太快会丢字节。实测50ms更安稳打印速度慢一点但成功率极高。一定要用队列方式等上一次success回调后再发下一次。不要在for循环里连续调用writeBLECharacteristicValue那会直接导致连接拥堵甚至断开。在比较新的Uniapp版本中如果Android端需要改MTU可以尝试uni.setBLEMTU但要在连接后、写数据前调用而且不是所有Android版本都支持。4. 打印内容怎么构造文本、图片、二维码4.1 文本直发为什么坑多如果只是打一两行纯英文数字文本直发没问题把字符串转ASCII字节加上换行塞进发送队列就行。但业务里的内容几乎都带中文、价格、手机号、地址。中文在Uniapp里是UTF-8编码而打印机内部常用GBK。直接在Uniapp里找到“字符串转GBK”的好用工具不多小程序环境里尤其头疼。另外文本模式下要对齐、加粗、调整字号每条都得拼对应的ESC/POS命令麻烦且容易出错。所以我的建议是业务小票统一走“图片打印”。把整张小票当成一张480x800像素的图片画在Canvas上转点阵发给打印机。这种方式能保证“所见即所得”也彻底绕开编码和排版命令的兼容性问题。4.2 图片转点阵的核心算法图片转点阵的流程分三步缩放、二值化、打包。第一步是缩放。Canvas里绘制的图片尺寸不一定是打印机的物理点阵尺寸。比如我们在大屏Canvas上画了一幅600x1000的内容图要打印成48mm宽就得缩放到384点宽。缩放的目的是让每个打印点对应一个像素避免打印效果发虚。第二步是二值化。热敏打印机没有灰度每个点只有“加热”和“不加热”。对每个像素计算灰度值大于阈值视为黑色打印小于阈值视为白色不打印。阈值最好根据实际打印效果微调我一般取128。说到最后一步我再细讲一下打包。ESC/POS位图数据按行组织每行宽度以字节为单位不足8点的部分用0补齐每个字节的bit位对应一行里的像素bit7代表最左边的点bit0代表最右边。这是最容易搞反的地方。function imageDataToPrinterBitmap(imageData) { const { data, width, height } imageData const rowBytes Math.ceil(width / 8) const bitmap [] for (let y 0; y height; y) { const rowStart y * width for (let xByte 0; xByte rowBytes; xByte) { let byte 0 for (let bit 0; bit 8; bit) { const px xByte * 8 bit if (px width) { const idx ((rowStart px) * 4) // RGBA const gray (data[idx] * 299 data[idx 1] * 587 data[idx 2] * 114) / 1000 const isBlack gray 128 if (isBlack) { byte | (0x80 bit) } } } bitmap.push(byte) } } return bitmap }这段代码的“黑点”判断是gray 128。如果你打印出来发现黑白色块反了把判断改成gray 128即可。这个问题经常被搞反打印出来的东西像“底片”就是这个原因。4.3 二维码与条码处理二维码和小票里经常出现。用Canvas绘制后它们自然成为图片的一部分不需要单独处理。在Uniapp App端我可以直接把二维码画到Canvas上。小程序端可以用现成的组件或js库生成二维码点阵后再绘制。绘制完后整张小票一并走uni.canvasGetImageData拿像素数据。一个小建议二维码的模块尺寸不要小于4个打印点否则打印机打出来的色块模糊扫码困难。打印宽度48mm、203dpi下一个30x30mm的二维码区域大约能放200x200点编码几十个字符的URL足够用。4.4 完整的ESC/POS指令组装数据准备好后拼指令的顺序是有讲究的发送初始化指令ESC 发送位图打印指令GS v 0携带位图数据发送几个换行指令让纸走出打印机方便撕离发送ESC J n走纸到切刀或撕纸位置代码层面就是把字节数组拼接起来function buildPrintCommand(bitmap, widthBytes, heightPoints) { // 初始化打印机 const init [0x1B, 0x40] // GS v 0 m xL xH yL yH 数据体 const header [0x1D, 0x76, 0x30, 0x00] const xL widthBytes 0xff const xH (widthBytes 8) 0xff const yL heightPoints 0xff const yH (heightPoints 8) 0xff // 为打印机留出适当的物理走纸空间走纸若干行 const feed [0x0A, 0x0A, 0x0A, 0x0A] return init.concat(header, [xL, xH, yL, yH], bitmap, feed) }几点经验补充位图宽度超过255字节时xH才有值384点宽的小票宽度只有48字节xH永远为0。但如果将来换80mm机宽度可能变成576点72字节依然在255以内。只有做宽幅标签时才会用到xH。高度按“点”为单位不是按字节。比如500像素高的图片在203dpi下就是500个点yL5000xff244yH1。GS v 0后面必须紧跟m这里固定是0x00代表正常模式。5. hiprint在方案里的正确用法5.1 hiprint的定位Web端排版与模板hiprint是个浏览量很大的Web打印插件功能核心是“模板设计器”支持拖拽文本、表格、图片、条码、二维码生成一套模板JSON。PC端可以调用它的打印能力走浏览器的打印机制把内容输出到USB/网络打印机上。但在Uniapp的App端hiprint的底层依赖DOM操作、iframe打印窗口不可用。你在门店App里没法直接new PrintTemplate(...).print()然后期望它调用蓝牙打印机。所以这里不要硬移植hiprint而是把它的价值“前置”用它在管理后台设计好小票模板导出一份JSON存到服务端Uniapp端拿到这份JSON按同样的布局在Canvas里画出来。5.2 推荐架构模板JSON Uniapp canvas渲染这套架构的优点很直接PC后台和美工负责样式移动端只负责“按图施工”。模板改版不用更新App只要后端更新JSON就可以。落地流程在PC端用hiprint设计模板导出模板JSON。后端接口下发模板JSON给Uniapp端。Uniapp端写一个轻量渲染器遍历模板里的元素逐个画到Canvas。Canvas内容转点阵走蓝牙发送给JLP352。hiprint模板JSON的结构大概是一个模板包含多个panel每个panel包含多个element。element有typetext、qrcode、image等、options坐标、宽高、字号和content实际内容。5.3 简化版的模板渲染示例这里给一个只支持文本和二维码的简化渲染器思路比完整实现都重要function renderTemplateToCanvas(canvasId, template, data) { const ctx uni.createCanvasContext(canvasId) const panel template.panels[0] const width panel.width * 8 // 面板宽度转像素每mm约8px const height panel.height * 8 panel.elements.forEach((el) { const left el.options.left * 8 const top el.options.top * 8 const elWidth el.options.width * 8 const elHeight el.options.height * 8 if (el.type text) { ctx.setFontSize(el.options.fontSize || 12) ctx.fillText(data[el.content] || el.content, left, top (el.options.fontSize || 12)) } else if (el.type qrcode) { // 调用二维码库生成图片然后绘制 drawQRCode(ctx, data[el.content] || el.content, left, top, elWidth, elHeight) } }) ctx.draw(false, () { // 绘制完成后取出像素数据 uni.canvasGetImageData({ canvasId, x: 0, y: 0, width, height, success: (res) { const bitmap imageDataToPrinterBitmap(res) // 拼指令并发送 } }) }) }注意模板里坐标单位需提前约定。hiprint的options通常以mm为单位而Canvas像素要和打印点阵对齐所以都换成“点”的单位才能保证实际打印尺寸正确。这里是容易出“打印出来偏小偏大”问题的根源。5.4 什么情况下直接抛弃hiprint不是所有项目都需要模板设计器。如果小票样式固定、改动频率低直接用代码在Canvas里写死布局更简单根本不用引入hiprint这套东西。Uniapp端用CSS、Canvas三元组画出固定小票转点阵打印就行。只有当下述条件满足时引入hiprint才划算门店很多不同门店的小票样式各不同且需要非开发人员调整。打印内容频繁走“模板化”需求比如不同的商品分类用不同的面单。你已经有PC端管理后台且需要用hiprint统一管理打印机和模板。否则别让模板系统成为负担。我见过一些项目为了“通用”而过度设计一个固定小票改了三个版本还没上线。6. 踩坑实录常见问题与排查思路6.1 设备搜不到先确认打印机不是处于“已连接”状态。手机系统设置里如果已经手动配对过该打印机Uniapp搜索时可能搜不到它或者搜到了但连接失败。解决方法是先在系统蓝牙里忽略/解绑该设备再回到App里扫描。Android上搜不到优先检查定位权限和GPS开关。Android的BLE扫描依赖定位服务位置权限没给onBluetoothDeviceFound不会触发。还有一个容易踩的打印机进入休眠后广播停止了。按一下打印机上的电源/出纸键唤醒它再扫描。6.2 连接上了但写不进去连得上说明BLE链路是通的写不进大概率是找错了特征值。打印机的BLE服务通常有多个特征值有的用于读写数据有的用于通知。只找properties.write为 true 的特征值可能找到两个你写的是配置特征值而不是数据特征值。稳妥方案是把所有特征值UUID和属性打日志逐个尝试写一小段初始化指令比如1B 40看打印机有没有反应。另外Android 6.0以下某些机型对writeBLECharacteristicValue的value类型要求严格必须是ArrayBuffer不要传普通数组。6.3 打印出来是乱码或空白乱码基本都是文本编码问题。你发送的是UTF-8字节打印机按GBK解析自然乱成一团。解决办法就是别发文本走图片位图。如果必须发文本需要自己做UTF-8到GBK的转换这在Uniapp端并不方便。空白则可能是指令拼错。最常见的就是GS v 0的参数顺序不对或者位图数据传成了空数组。建议先把指令组装函数单独抽出来固定打印一小块56x56的纯黑色位图测试确认打印机“吃”这个指令后再塞真数据。6.4 Android/iOS差异与兼容iOS端连接BLE外设稳定但MTU按20字节走大数据会慢一点。Android端不同ROM对BLE的实现差异明显。比如小米手机默认可能限制后台蓝牙扫描华为手机上某些系统版本要求同时开启“附近设备”权限。iOS上如果device.name为空无法按名称过滤。此时可以读取广播数据里的manufacturerData或者让用户手动从扫描列表里选择一台设备连接。部分Android手机连接成功后CPU休眠会导致写入中断发送大量数据时最好在异步队列里用定时器“喂”数据避免长时间无写入。6.5 其他奇奇怪怪的问题打印出来整体偏移、内容截断、图片模糊这三个问题高频出现现象原因解决内容整体偏移未初始化打印机残留上次标签定位先发1B 40内容截断高度yL yH算错位图高度与数据量不匹配用实际像素高度计算yL yH模糊图片宽度未对齐打印机物理点数宽度必须缩放到384点整不要用任意尺寸还有一个细节GS v 0的位图数据是按行拼接的行与行之间不要插入任何额外字节否则打印出来的图像会出现斜向错位。我遇到过有人在每行数据后加了换行指令结果整张图变成了“水平条错位”排查了很久。最后再分享一个实用习惯打印机指令调试时准备一个“十六进制发送面板”用Uniapp页面做一个输入框和发送按钮直接粘贴十六进制字符串发送。比如发1B 40 0A看打印机是否走纸。这个面板能快速区分“问题在数据构造”还是“问题在链路传输”是我每次对接新打印机的第一件事。对接完成后这个面板还可以留给现场实施同事做诊断用省掉很多远程沟通成本。

相关新闻

连连看综合实验:界面设计与数据结构算法拆解

连连看综合实验:界面设计与数据结构算法拆解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 4:49:25 阅读更多 →
2020前端面试复盘:高频考点与求职策略全解析

2020前端面试复盘:高频考点与求职策略全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 4:49:25 阅读更多 →
Ubuntu 上自建代码托管平台:程序包安装与运维实战指南

Ubuntu 上自建代码托管平台:程序包安装与运维实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 4:49:25 阅读更多 →

最新新闻

Python入门必破关:PTA判题机制与输出输入规范解析

Python入门必破关:PTA判题机制与输出输入规范解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 5:29:36 阅读更多 →
VS2019+EasyX实现简易坦克射击游戏

VS2019+EasyX实现简易坦克射击游戏

1. 项目概述:为什么一个“简易坦克射击游戏”值得花时间重做一遍在某高校计算机基础课的实训环节里,我连续三年带学生做图形化小项目,从贪吃蛇、扫雷到推箱子,直到去年有位同学交上来一份用VS2019 EasyX写的坦克对战Demo——虽然…

2026/10/16 5:29:36 阅读更多 →
Element Plus el-tooltip 样式定制:宽度与字体设置详解

Element Plus el-tooltip 样式定制:宽度与字体设置详解

1. 项目概述Element Plus 的 el-tooltip 是个好用但有时候让人挠头的组件。默认效果很干净,悬停弹出一个小气泡,但当产品经理说“这个提示文字太挤了,放宽一点”“这个字号太小了看不清”的时候,你会发现默认样式怎么改都不太对劲…

2026/10/16 5:29:36 阅读更多 →
基于MP2642GR-Z和PIC18F87K22的2S电池组主动均衡方案设计

基于MP2642GR-Z和PIC18F87K22的2S电池组主动均衡方案设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 5:29:36 阅读更多 →
C#实战:JSON转Excel导出的完整方案与性能优化

C#实战:JSON转Excel导出的完整方案与性能优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 5:29:36 阅读更多 →
OpenPose实战避坑指南:多人姿态估计与骨骼角度计算

OpenPose实战避坑指南:多人姿态估计与骨骼角度计算

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 5:28:35 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →