上周又碰到那个问过不下二十次的问题导出的报表里“部门”这一列每行都重复客户要求把相同部门合成一格看起来干净。每次聊到最后都绕不开 EasyPOI 合并单元格这套东西。注解上一个 needMerge true 看着轻巧真丢进业务里问题一个接一个跨组误合并、合并后边框全丢、导入时只读到左上角的值、数据量一大整个导出卡住。这篇就把我这些年在这上面趟出来的路完整写一遍从注解路线到动态 Map 路线从导出合并到导入展开把容易翻车的地方都标出来。适合刚接手 Excel 报表导出、被合并单元格折磨过的同学也适合已经能跑通但总在细节上返工的老手。1. 合并单元格这件事EasyPOI 到底帮你做了多少很多人对 EasyPOI 的期待是“我加个注解它就该把所有合并都搞定”结果发现有的地方合了、有的地方没合于是开始怀疑人生。实际上 EasyPOI 只覆盖了合并需求里最标准的那一部分剩下的边界它留给你自己处理搞清楚它管到哪一步后面写代码就不会拧巴。1.1 三种合并场景别混为一谈我在项目里遇到的合并需求摊开来看就三类它们的实现位置完全不同混着做必然出问题。第一类是表头多级合并。比如“基本信息”下面挂“姓名、性别、年龄”三列“联系方式”下面挂“电话、邮箱”三列这里要在表头上方生成横向的合并格。这类合并在“写表头”阶段完成EasyPOI 的 groupName 就是干这个的不需要你碰 POI 的任何 API。第二类是数据区纵向合并。同一列里相邻且值相同的单元格合成一个典型如部门、区域、分类这些维度列。这类合并在“数据写完之后”进行因为要比较相邻行的值才能决定合不合EasyPOI 的 needMerge 走的就是这条路。第三类是复杂报表式合并比如最后一行做“合计”跨列合并、动态区域的合并、或者带合并的模板填充。这类需求 EasyPOI 的注解模型撑不住必须拿到 Workbook 之后自己调 addMergedRegion 处理。把这三类分清之后你会发现大部分“EasyPOI 合并没用”的抱怨其实是把第三类需求硬塞给第二类的参数去解决。先判断手上的需求属于哪一类比急着改注解重要得多。1.2 为什么 EasyPOI 用 needMerge 而不是让你直接调 POI直接写 POI 的话合并一个区域需要两行代码sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, col, col))问题是你得自己算出 firstRow 和 lastRow也就是自己做相邻值比较。EasyPOI 把这套比较逻辑封装进 needMerge省掉的是这部分循环代码但它的实现有个隐含前提只合并上下相邻且值相同的行。这个前提带来的直接后果是数据必须提前排好序。如果部门列的数据是 A、B、A 这样散着来的EasyPOI 只会把相邻的两段各自合并出现两个“A”的合并块视觉上看着就像没生效。我见过有人排查了一下午注解写错没最后发现是 SQL 少了 order by。另一个前提是合并范围从数据区起始行开始不包含表头。表头行的合并不走 needMerge走的是 groupName两条线互不干扰。理解这两点后面很多“玄学问题”就有解释了。2. 注解路线静态表头导出的合并姿势实体类固定的场景注解是最省事的路子。列是编译期确定的字段名、顺序、宽度都能在注解里写死改起来也直观。但注解路线有几个参数容易用错尤其是分组合并那里。2.1 groupName 管表头needMerge 管数据区先看一个典型的导出实体订单明细带两级表头Data public class OrderExportVO { Excel(name 订单编号, orderNum 1, width 22) private String orderNo; Excel(name 部门, groupName 基本信息, orderNum 2, width 16, needMerge true) private String deptName; Excel(name 负责人, groupName 基本信息, orderNum 3, width 14, needMerge true) private String owner; Excel(name 金额, groupName 交易信息, orderNum 4, width 14, numFormat #,##0.00) private BigDecimal amount; Excel(name 下单时间, groupName 交易信息, orderNum 5, width 20, format yyyy-MM-dd HH:mm:ss) private Date createTime; }导出调用三行ExportParams params new ExportParams(订单明细, 明细); params.setHeaderHeight(22); Workbook workbook ExcelExportUtil.exportExcel(params, OrderExportVO.class, dataList); try (OutputStream out new FileOutputStream(order.xlsx)) { workbook.write(out); }跑出来的效果是表头第一行出现“基本信息”“交易信息”两个横向合并块第二行是各列名数据区里“部门”和“负责人”两列会按相邻相同值纵向合并。这里有个细节必须说清楚groupName 相同的列必须相邻。EasyPOI 是按 orderNum 排序后从头到尾扫的遇到 groupName 变化就切块。如果你的 orderNum 写成 1、3、2 这种乱序两个“基本信息”列中间被“交易信息”插了一刀表头上就会冒出两个“基本信息”块而不是合成一个。这个现象我第一次遇到时还以为是 Bug翻源码才明白它是顺序扫描。提示orderNum 要么全部写要么全部不写靠字段声明顺序最忌讳写一半。混着来的时候 EasyPOI 的排序结果很难预判。2.2 mergeRely解决“跨组误合并”的关键参数needMerge 单独用的最大问题就是它只比较本列的值不关心别的列。举个真实场景一张按“部门 负责人”两级分组的表负责人列上打了 needMerge。假如部门 A 有“张三”部门 B 也有“张三”两行在表里是相邻的因为先按部门排两个部门的边界正好挨着EasyPOI 一看负责人列上下都是“张三”啪一下合了——结果这个合并格跨了两个部门看着就像张三同时管两个部门。解决参数是mergeRely告诉 EasyPOI“这一列的合并要以某某列为分组边界”Excel(name 负责人, groupName 基本信息, orderNum 3, width 14, needMerge true, mergeRely {deptName}) private String owner;加上之后只有 deptName 相同且 owner 相同的相邻行才会合并。多级分组就往后加比如部门 小组 负责人三级负责人列的 mergeRely 写{deptName, groupName}从粗到细一层层约束。动态导出的写法是entity.setMergeRely(new String[]{deptName})参数类型是 String 数组对应 Map 里的 key 名。这里特别容易写错的是依赖列必须是同一个导出模型里真实存在的字段/key写错了不会报错只是合并结果不对排查起来相当难受。2.3 注解方式的边界在哪注解路线有两个明显天花板。一是列不能动态变导出字段一旦要在运行期根据用户勾选决定注解就废了得换 ExcelExportEntity 动态构建。二是合并逻辑写死在注解里做不了“根据某个字段值决定这一行合不合并”这种条件逻辑。还有个隐蔽的坑注解加在 Lombok 生成的 getter 上偶尔会失效。原因不复杂Excel 默认作用在字段上EasyPOI 反射读字段值如果你在字段上加了 Excel 但同时用了Accessors(fluent true)这类改变 getter 命名的配置某些版本反射拿不到值导出的列是空的或者合并判断恒为相同。稳妥做法是老老实实保持标准 getter/setter 命名别在导出实体上玩花活。3. 动态路线List导出时的合并控制列要动态决定的项目里注解路线走不通只能换成 ExcelExportEntity 构建表头数据用 List传。这条路灵活度高参数一样不少但需要你自己保证 key 的一致性。3.1 ExcelExportEntity 的构建与 needMerge 生效条件核心对象就一个每个导出的列对应一个 ExcelExportEntityname 是表头显示的文字key 是 Map 里取值的键。合并相关的三个方法是 setNeedMerge、setMergeRely、setGroupName语义和注解一一对应。ListExcelExportEntity entityList new ArrayList(); ExcelExportEntity dept new ExcelExportEntity(部门, deptName); dept.setWidth(18); dept.setNeedMerge(true); entityList.add(dept); ExcelExportEntity owner new ExcelExportEntity(负责人, owner); owner.setWidth(15); owner.setNeedMerge(true); owner.setMergeRely(new String[]{deptName}); entityList.add(owner); ExcelExportEntity amount new ExcelExportEntity(金额, amount); amount.setWidth(15); amount.setNumFormat(#,##0.00); entityList.add(amount);数据准备ListMapString, Object rows new ArrayList(); for (Order o : orderList) { MapString, Object row new LinkedHashMap(); row.put(deptName, o.getDeptName()); row.put(owner, o.getOwner()); row.put(amount, o.getAmount()); rows.add(row); } Workbook workbook ExcelExportUtil.exportExcel(params, entityList, rows);key 必须和 ExportEntity 里的 key 完全一致大小写、下划线都不能差。差一个字符的表现是那一列整列空白而合并逻辑因为取不到值会把这些空值当成“全部相同”做出一个巨大的跨行合并格。这个现象很有迷惑性看到合并区域异常大第一反应应该去查 key 拼写而不是查合并参数。3.2 动态表头 两级分组合并的完整实现真实报表往往要“动态列 分组表头 分组内合并”三件套一起上。下面这段是我在项目里用过的骨架包含部门表头分组和部门内的负责人合并public Workbook buildReport(ListOrder list, ListString dynamicCols) { ListExcelExportEntity cols new ArrayList(); ExcelExportEntity deptName new ExcelExportEntity(部门, deptName); deptName.setWidth(18); deptName.setNeedMerge(true); deptName.setGroupName(组织信息); cols.add(deptName); ExcelExportEntity owner new ExcelExportEntity(负责人, owner); owner.setWidth(15); owner.setNeedMerge(true); owner.setMergeRely(new String[]{deptName}); owner.setGroupName(组织信息); cols.add(owner); for (String col : dynamicCols) { ExcelExportEntity dyn new ExcelExportEntity(col, col); dyn.setWidth(14); dyn.setGroupName(业务指标); cols.add(dyn); } // 排序是合并生效的前提 list.sort(Comparator.comparing(Order::getDeptName) .thenComparing(Order::getOwner)); ListMapString, Object rows new ArrayList(); for (Order o : list) { MapString, Object row new LinkedHashMap(); row.put(deptName, o.getDeptName()); row.put(owner, o.getOwner()); for (String col : dynamicCols) { row.put(col, o.getMetric(col)); } rows.add(row); } ExportParams params new ExportParams(部门业绩, 业绩); return ExcelExportUtil.exportExcel(params, cols, rows); }注意中间那段排序它不是可选项。动态列场景下数据来源常常是多个查询拼起来的顺序天然是乱的不排序就直接导出合并效果会变成一段一段的碎片。3.3 版本差异与依赖对齐EasyPOI 几个大版本之间合并相关的 API 名字没变但底层 POI 版本一直在跟。4.x 系列围绕 POI 3.17 到 4.x 走5.x 系列上了 POI 5.x。麻烦的是项目里如果已经有别的组件间接依赖了另一个 POI 版本Maven 会做仲裁最后跑起来可能抛NoClassDefFoundError: org/apache/poi/ss/usermodel/Workbook这种看着很吓人的错。排查方法很土但有效mvn dependency:tree -Dincludesorg.apache.poi看最终生效的是哪个版本然后显式在 pom 里锁死。合并单元格相关的CellRangeAddress、getMergedRegions()在不同 POI 版本里返回类型有过变化早期版本返回数组后来是 List代码里别写死类型用ListCellRangeAddress配合对应版本即可。4. 落地实操从依赖到跑通的最小闭环光说参数不动手等于没学。这一节把完整的可运行链路走一遍包括合并之后怎么补齐样式因为这一步几乎每个项目都要做。4.1 依赖与基础准备Spring Boot 项目直接上 starter省掉手动管 POI 版本dependency groupIdcn.afterturn/groupId artifactIdeasypoi-spring-boot-starter/artifactId version4.4.0/version /dependency非 Boot 项目按需引三个包easypoi-base、easypoi-annotation、easypoi-web。web 包只有在你需要从 HttpServletResponse 直接输出时才用得上。依赖进来之后第一件事是写一个只有两列的 Demo 跑通链路别一上来就往真实业务模型上套。我踩过的坑是直接在二十个字段的导出类上加注解出问题时根本无法判断是注解写错、排序没做、还是依赖冲突排查成本翻了好几倍。4.2 完整可运行的导出代码一个带合并、带样式、输出到文件的最小例子public void exportWithMerge(ListOrderExportVO list) throws IOException { // 1. 排序合并的前提 list.sort(Comparator.comparing(OrderExportVO::getDeptName, Comparator.nullsFirst(String::compareTo)) .thenComparing(OrderExportVO::getOwner, Comparator.nullsFirst(String::compareTo))); // 2. 导出参数 ExportParams params new ExportParams(订单明细, 明细); params.setHeaderHeight(24); params.setStyle(ExcelStyleType.BORDER_THIN.getExcelStyle()); // 3. 导出 Workbook workbook ExcelExportUtil.exportExcel(params, OrderExportVO.class, list); // 4. 补齐合并区域的边框 repairMergedBorder(workbook); try (OutputStream out new FileOutputStream(/tmp/order.xlsx)) { workbook.write(out); } }ExcelStyleType.BORDER_THIN是 EasyPOI 自带的样式枚举给所有单元格加细边框。这个参数解决的是“表头和数据格都有框”的问题但解决不了合并区域里被吞掉的那些格子所以第 4 步还得单独补。4.3 用 Workbook 后处理兜底自定义合并与样式补齐拿到 Workbook 之后可以做注解做不到的事情。下面这个方法把每个合并区域内部的单元格样式统一成左上角的样式边框就回来了private void repairMergedBorder(Workbook workbook) { Sheet sheet workbook.getSheetAt(0); CellStyle template workbook.createCellStyle(); template.cloneStyleFrom(sheet.getRow(1).getCell(0).getCellStyle()); template.setBorderTop(BorderStyle.THIN); template.setBorderBottom(BorderStyle.THIN); template.setBorderLeft(BorderStyle.THIN); template.setBorderRight(BorderStyle.THIN); template.setAlignment(HorizontalAlignment.CENTER); template.setVerticalAlignment(VerticalAlignment.CENTER); for (CellRangeAddress region : sheet.getMergedRegions()) { for (int r region.getFirstRow(); r region.getLastRow(); r) { Row row sheet.getRow(r); if (row null) { row sheet.createRow(r); } for (int c region.getFirstColumn(); c region.getLastColumn(); c) { Cell cell row.getCell(c); if (cell null) { cell row.createCell(c); } cell.setCellStyle(template); } } } }这里有两个必须注意的点。其一cloneStyleFrom复制的是样式引用之后改模板样式会影响所有克隆出来的格所以模板要一次性定好再往下刷。其二给合并区域内的非左上角单元格设样式是安全的但如果你的逻辑是先设样式再 addMergedRegionPOI 在某些版本会把区域内格子的样式清掉顺序应该是先合并后刷样式。还有一种情况是数据区之外的合并比如最后一行写“合计”然后横向合并五列int lastRow sheet.getLastRowNum() 1; Row totalRow sheet.createRow(lastRow); Cell label totalRow.createCell(0); label.setCellValue(合计); sheet.addMergedRegion(new CellRangeAddress(lastRow, lastRow, 0, 4));单行合并会抛Merged region A1:E1 must contain 2 or more cells因为只有一行的区域在 POI 看来不构成合并格。想给单行做视觉上的“占位”正确做法是合并列方向而不是行方向别在行方向硬凑。5. 导入侧合并单元格读不到值的坑怎么填导出写完只是前半程很多项目还要把这批文件导回来。合并单元格在读取时是重灾区表现是同一个部门只有第一行能读到值后面全空业务上直接把这些人分到了“未分配”。5.1 现象与成因根本原因在文件格式本身合并单元格在 xlsx 里只保留左上角那个格子的值其余格子虽然是空的但在视觉上被合并区域盖住了。POI 读取时不会自动把值复制到整个区域EasyPOI 的导入流程也只是逐行逐格读读到空格就给 null。所以问题不在 EasyPOI 有 Bug而在于“合并”这个动作本身就把数据稀疏化了。你在 Excel 里看到的满满一列底层其实只有一个值。解决方案分两档轻量方案是在业务层做“向下填充”即遍历导入结果遇到空值就沿用上一个非空值并加一个字段标记它是补全来的。这个方案实现最省事但只对“纵向合并且值沿列向下延续”的场景成立一旦合并区域跨列或者有多层就不靠谱了。5.2 预处理展开合并区域的可复制方案稳妥做法是在交给 EasyPOI 之前先用 POI 把合并区域展开成满格值。思路是读入 Workbook遍历所有合并区域把左上角的值和样式刷到区域内每个格子再输出成字节流给 EasyPOI 用。public ImportResult? importWithMergeFilled(InputStream in, Class? clazz) throws Exception { Workbook wb WorkbookFactory.create(in); Sheet sheet wb.getSheetAt(0); for (CellRangeAddress region : new ArrayList(sheet.getMergedRegions())) { Row firstRow sheet.getRow(region.getFirstRow()); if (firstRow null) { continue; } Cell firstCell firstRow.getCell(region.getFirstColumn()); if (firstCell null) { continue; } String value readCellAsString(firstCell); for (int r region.getFirstRow(); r region.getLastRow(); r) { Row row sheet.getRow(r); if (row null) { row sheet.createRow(r); } for (int c region.getFirstColumn(); c region.getLastColumn(); c) { Cell cell row.getCell(c); if (cell null) { cell row.createCell(c); } if (r region.getFirstRow() c region.getFirstColumn()) { continue; } cell.setCellValue(value); cell.setCellStyle(firstCell.getCellStyle()); } } } ByteArrayOutputStream bos new ByteArrayOutputStream(); wb.write(bos); wb.close(); ImportParams params new ImportParams(); params.setHeadRows(2); return ExcelImportUtil.importExcel( new ByteArrayInputStream(bos.toByteArray()), clazz, params); }readCellAsString需要按单元格类型分支处理数值型用BigDecimal.valueOf(cell.getNumericCellValue()).stripTrailingZeros().toPlainString()转避免出现1.0这种尾巴日期型走getDateCellValue()加格式化。这个方案的开销是要把整个文件读进内存再写一遍。十万行以内没什么感觉更大的文件就得考虑流式处理或者换用能逐块处理的方案。另外展开之后合并区域依然存在EasyPOI 读值不受影响但如果后续要用行号定位注意别把展开出来的重复行当成了冗余数据。5.3 业务层补全值的轻量做法不是所有项目都值得为导入写一套预处理。如果合并只发生在固定的一两列在导入结果上做一次向下填充更划算String lastDept null; for (OrderImportVO vo : result.getList()) { if (StringUtils.isBlank(vo.getDeptName())) { vo.setDeptName(lastDept); } else { lastDept vo.getDeptName(); } }这个循环的隐含风险是如果用户导了一个本来就有空行的表空行会被错误地填上上一行的值。防呆手段是加一列隐藏的行号做校验或者要求模板里不允许出现整行空白。我们项目里的做法是在模板说明里写明“部门列为空表示继承上一行”把责任前置到填表人比在代码里猜要稳。6. 样式、性能与常见报错速查最后这一节是我这些年攒下来的碎片经验都是文档里不会写、但每次做合并报表都可能撞上的东西。6.1 合并后边框丢失的修复EasyPOI 合并时保留左上角格子的样式区域内的其他格子样式被丢弃导致原本有框的表格在合并处出现缺口。修复思路就是第 4.3 节那段代码拿到合并区域后统一样式。但有个更省事的做法值得提一句——如果你用的是 EasyPOI 自带样式模板可以在 ExportParams 里指定setStyle让它在合并前就把边框刷满合并后缺口会小很多。另外行高问题常被忽略。合并区域跨越了多行时行高仍然是那几行各自的行高之和如果给每行设了自动换行合并后的文字会挤在左上角显示不全。要么固定行高要么合并前把内容截断别指望自动换行在合并区域里表现正常。6.2 大数据量与合并的冲突数据量上到十万行级别合并就是性能瓶颈。EasyPOI 的合并逻辑对每一列从底往上扫一遍比较相邻单元格的值单元格读取本身不快列数多了之后耗时肉眼可见。我实测过八万行、十二列、其中四列需要合并的场景导出耗时从两秒涨到十一秒主要开销就在反复读 cell。更麻烦的是大数据量导出通常要换用exportBigExcel它底层是 SXSSFWorkbook只保留窗口内的行在内存里。SXSSF 对已写出的行做合并会出问题可能出现合并区域错位、文件打不开。经验是需要大量合并的报表别用流式导出或者把合并降到最少列再或者拆成多个 sheet 分批导出。反过来不需要合并的宽表用流式导出收益很明显这两件事别硬凑一起。6.3 问题速查表与实操心得现象最可能的原因处理方式相同值没有合并数据未排序相同值不相邻导出前按分组列排序合并跨越了不同分组缺少 mergeRely设置依赖列从粗到细约束整列被合并成一个巨大的格取值的 key 写错全是 null核对 ExcelExportEntity 的 key 与 Map 一致表头出现两个重复的分组同 groupName 的列被其他列隔开调整 orderNum 让同组列相邻合并处没有边框合并吞掉了区域内格子样式合并后遍历 region 统一刷样式导入只读到第一行合并单元格底层只存左上角值预处理展开区域或业务层向下填充报 Merged region must contain 2 or more cells对单行做行方向合并改成列方向合并别合单行报 region overlaps自定义合并与 needMerge 区域重叠先执行内置合并再按区域判断后补打开文件提示损坏SXSSF 流式导出中做了跨窗口合并改用普通导出或拆 sheet再说几个不太上表的心得。boolean 和数值列的合并判断。needMerge 比较的是单元格呈现出来的值数值型经过 numFormat 之后可能都是“1,000.00”两个不同的数格式化后看起来一样时不会误合因为比较发生在格式化之前但反过来同一个小数在不同单元格里因为精度差异呈现出不同字符串时会漏合。金额列我一般直接保留 BigDecimal 原值比较不额外格式化后再判断。合并与自动筛选冲突。带合并单元格的表做自动筛选筛出来的结果会缺行这是 Excel 自身的行为不是导出的问题。我的处理是需要筛选的报表就干脆不合并靠隔行变色区分分组需要观感的报表才合并。两个诉求别强行在一张表上满足。模板导出里的合并。用 EasyPOI 的模板导出TemplateExportParams做合并合并动作要放在模板里预设而不是代码里动态生成。模板里预先画好合并区域代码只负责填值稳定得多。模板里的合并区域如果和数据行数不匹配表现是值填到了错误的位置检查方法是先把模板导出一次空数据看看区域对不对。导出后再排序会毁掉合并。有些同学导出完交给用户用户在 Excel 里按金额排序合并区域就散架了。这不是技术问题是使用约定问题交付时把“本表含合并单元格请勿直接排序”写进说明比事后解释省事。我个人在做这类报表时的体会是先问清楚这张表是给人看还是给机器读。给人看的合并、边框、居中该做就做给机器读的一个合并都别加平铺数据最省心。以前有个项目两类需求混在一张表里结果是对账脚本每次都要先把合并区域展开多写了一百多行补丁代码。这个内容后面还可以往模板化方向延伸把常用的分组合并在模板层面固定下来代码只管数据改报表样式的时候不用动 Java维护成本会低很多。
企业数字化 ERP 产品动态
相关推荐
外包职场真相:权限隔离、福利歧视与发展限制 1. 外包行业的职场真相:从零食事件看身份差异去年那则外包员工因吃零食被HR训斥的帖子,至今仍在测试圈引发热议。作为在IT行业摸爬滚打十年的老兵,我亲眼见证过太多类似场景:某外包测试员使用公司健身房被拦下、节日礼盒发放时被刻… · 2026/11/3 16:29:49
边缘AI芯片选型实战:从场景需求到算力匹配的完整指南 1. 边缘端 AI 算力选型的底层逻辑
1.1 为什么“从场景反推芯片”才是正确姿势 做边缘 AI 项目,最容易踩的坑就是先选芯片再想场景。我见过太多团队一上来就盯着算力参数表,比谁家的 TOPS 数字大,结果板子打回来发现功耗压不住、接口对不上、… · 2026/11/3 16:29:49
Selenium4升级实战:从兼容性问题到最佳实践 1. 从Selenium3到Selenium4的升级历险记作为一名长期从事自动化测试的老兵,我最近在升级Selenium时踩了个大坑。事情是这样的:看到Selenium4官方宣传的重大更新后,我兴冲冲地执行了pip install -U selenium,结果原本运行良好的测试… · 2026/11/3 16:29:49
Selenium自动化测试:电子忏悔室与赎罪券生成实践 1. 项目背景与核心思路 这个看似荒诞的项目标题"用Selenium操控教堂:电子忏悔室自动生成赎罪券"实际上是一个极具创意的技术实验。它巧妙地将自动化测试工具Selenium的应用场景扩展到了宗教领域,构建了一个能够模拟人类操作、自动完成电子忏悔… · 2026/11/3 22:42:25
多人同时编辑Excel:共享地址、权限与协作规范实战 1. 多人同时编辑Excel,真正的拦路虎不在软件功能每到季度末、项目节点、盘点周期,办公室里最容易出现的一幕就是:五个人分头填同一张表,收上来五个附件,文件名依次是"汇总表.xlsx""汇总表-修改.xlsx&qu… · 2026/11/3 22:42:25
88E1512千兆以太网PHY调试:RGMII/SGMII、EEE与VCT排查 简介:Marvell 88E1512 芯片数据手册,面向以太网PHY选型、硬件原理图设计及嵌入式网络调试人员,用于快速掌握这款集成10/100/1000 Mbps节能以太网收发器的功能定位、性能边界与设计约束。压缩包仅含1个PDF文件,大小约1.05MB&#x… · 2026/11/3 22:42:25
一人公司运营实战:政策、成本与效率优化 1. 一人公司的政策背景与市场环境2023年新修订的《公司法》正式实施后,一人有限责任公司(自然人独资)的注册门槛显著降低。最明显的变化是取消了注册资本实缴要求,改为完全的认缴制。这意味着创业者可以用1元注册资本成立公司&… · 2026/11/3 22:42:25
EDID 128字节字段解析与HDMI扩展块生成校验 简介:本资源是一份面向显示驱动开发、硬件调试与显示器固件工程师的EDID编程规范文档,聚焦扩展显示识别数据(EDID)这一显示终端与信号源之间的信息交换结构。内容从数据结构层面拆解128字节基本块(可扩展至256字节&… · 2026/11/3 22:42:24
条码标签打印软件流水号跳号设置与漏号排查指南 条码标签打印软件里最容易被做成“事故”的一个功能,就是流水号。我这些年帮不少仓库、产线、门店处理过标签打号的问题,其中问得最集中的一类就是——为什么我的流水号打出来是跳号的。有意思的是,“跳号”这个词在条码标签打印软件里其实是… · 2026/11/3 22:41:24
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46