Vue3结合vue-plugin-hiprint实现自定义打印模板设计与布局

简介

在现代Web应用开发中,打印功能是不可或缺的一部分,尤其是在需要输出标准化文档的场景下。本文将详细介绍如何在Vue3项目中利用vue-plugin-hiprint插件实现一个可定制的打印模板设计器,并通过具体示例来展示其配置与使用方法。

技术栈

本项目基于以下技术栈:

  • Vue3
  • TypeScript (Ts)
  • Element Plus
  • Vite

插件安装

首先通过npm安装vue-plugin-hiprint插件:

npm install vue-plugin-hiprint

main.ts引入组件

在项目的入口文件main.ts中引入hiPrintPlugin并注册到Vue应用实例上。同时引入全局CSS(从node_modules/vue-plugin-hiprint/dist/目录下复制一份print-lock.css到静态资源目录下)。

import { createApp } from 'vue';
import App from './App.vue';
// 引入全局CSS  
import './assets/public/print-lock.css'  
import { hiPrintPlugin } from 'vue-plugin-hiprint';

hiPrintPlugin.disAutoConnect(); // 取消自动连接直接打印客户端
const app = createApp(App);
app.use(hiPrintPlugin, '$pluginName');

CSS样式配置

为了确保打印效果符合预期,在原有的print-lock.css基础上进行了扩展和调整,以适应不同的浏览器环境,尤其是Firefox浏览器中可能出现的打印重叠问题。如下是个人的iconfont.css,等会主组件要用,这里面的SVG字体样式后台评论区将提供:

@font-face {
  font-family: "iconfont"; /* Project id 3559670 */
  src: url("iconfont.woff2?t=1667531544868") format("woff2"),
    url("iconfont.woff?t=1667531544868") format("woff"),
    url("iconfont.ttf?t=1667531544868") format("truetype");
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.sv-edit-data:before {
  content: "\e655";
}

.sv-shimmer:before {
  content: "\e6d6";
}

.sv-origin:before {
  content: "\e6ac";
}

.sv-zIndex:before {
  content: "\e603";
}

.sv-structure:before {
  content: "\ec6f";
}

.sv-list:before {
  content: "\e742";
}

.sv-grid:before {
  content: "\e849";
}

.sv-flow:before {
  content: "\e611";
}

.sv-switch:before {
  content: "\e6f6";
}

.sv-theme:before {
  content: "\e644";
}

.sv-element:before {
  content: "\e615";
}

.sv-pdf:before {
  content: "\e67a";
}

.sv-browser:before {
  content: "\e726";
}

.sv-font-big:before {
  content: "\eb04";
}

.sv-font-small:before {
  content: "\eb05";
}

.sv-font-bold:before {
  content: "\ec83";
}

.sv-font-tiny:before {
  content: "\e6c1";
}

.sv-options:before {
  content: "\e607";
}

.sv-close:before {
  content: "\e646";
}

.sv-clone:before {
  content: "\ec7a";
}

.sv-cut:before {
  content: "\e643";
}

.sv-preview:before {
  content: "\e61c";
}

.sv-zoom-in:before {
  content: "\e60f";
}

.sv-zoom-out:before {
  content: "\e610";
}

.sv-edit:before {
  content: "\e6b9";
}

.sv-paste:before {
  content: "\e6c0";
}

.sv-copy:before {
  content: "\e6c2";
}

.sv-unlock:before {
  content: "\e6e7";
}

.sv-lock:before {
  content: "\e6e8";
}

.sv-zIndex-plus:before {
  content: "\e715";
}

.sv-zIndex-minus:before {
  content: "\e716";
}

.sv-zIndex-top:before {
  content: "\e71f";
}

.sv-sigh:before {
  content: "\e724";
}

.sv-ask:before {
  content: "\e725";
}

.sv-dev-code:before {
  content: "\e733";
}

.sv-bug:before {
  content: "\e73f";
}

.sv-zIndex-bottom:before {
  content: "\e71d";
}

.sv-new:before {
  content: "\e64d";
}

.sv-clear:before {
  content: "\e62d";
}

.sv-base:before {
  content: "\e7d0";
}

.sv-export:before {
  content: "\eabf";
}

.sv-import:before {
  content: "\eac0";
}

.sv-add:before {
  content: "\eaf3";
}

.sv-printer:before {
  content: "\eabe";
}

.sv-save:before {
  content: "\eabd";
}

.sv-more:before {
  content: "\e625";
}

.sv-menu:before {
  content: "\e628";
}

.sv-nav-right:before {
  content: "\e629";
}

.sv-nav-up:before {
  content: "\e62a";
}

.sv-nav-left:before {
  content: "\e62b";
}

.sv-nav-down:before {
  content: "\e62c";
}

.sv-setting:before {
  content: "\e62e";
}

.sv-delete:before {
  content: "\e630";
}

.sv-undo:before {
  content: "\e631";
}

.sv-redo:before {
  content: "\e632";
}

.sv-refresh:before {
  content: "\e634";
}

.sv-history:before {
  content: "\e635";
}

.sv-html:before {
  content: "\e633";
}

.sv-longText:before {
  content: "\e64c";
}

.sv-table:before {
  content: "\ec15";
}

.sv-qrcode:before {
  content: "\e642";
}

.sv-image:before {
  content: "\e8ba";
}

.sv-barcode:before {
  content: "\eb64";
}

.sv-text:before {
  content: "\e60b";
}

.sv-vline:before {
  content: "\e63a";
}

.sv-oval:before {
  content: "\eb99";
}

.sv-rect:before {
  content: "\e620";
}

.sv-hline:before {
  content: "\e60a";
}

.sv-print-c:before {
  content: "\e602";
}

.sv-print:before {
  content: "\e601";
}

.sv-c:before {
  content: "\e600";
}

.sv-vertical:before {
  content: "\e706";
}

.sv-distributeHor:before {
  content: "\e707";
}

.sv-right:before {
  content: "\e708";
}

.sv-left:before {
  content: "\e709";
}

.sv-distributeVer:before {
  content: "\e70f";
}

.sv-bottom:before {
  content: "\e710";
}

.sv-top:before {
  content: "\e711";
}

.sv-horizontal:before {
  content: "\e712";
}

.sv-rotate:before {
  content: "\e66f";
}

.sv-butongbu:before {
  content: "\e636";
}

.sv-synchronization:before {
  content: "\e676";
}
/* 重写全局 hiprint 样式 */
.hiprint-headerLine,
.hiprint-footerLine {
  border-color: purple !important;
}

.hiprint-headerLine:hover,
.hiprint-footerLine:hover {
  border-top: 3px dashed purple !important;
}

.hiprint-headerLine:hover:before {
  content: "页眉线";
  left: calc(50% - 18px);
  position: relative;
  background: #ffff;
  top: -14px;
  color: purple;
  font-size: 12px;
}

.hiprint-footerLine:hover:before {
  content: "页脚线";
  left: calc(50% - 18px);
  position: relative;
  color: purple;
  background: #ffff;
  top: -14px;
  font-size: 12px;
}
/* 区域 */
.left {
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 10px 0;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}
.center {
  margin: 0 10px;
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 20px;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}
.right {
  background: white;
  border-radius: 4px;
  border: 1px solid #d9d9d9;
  padding: 10px 0;
  box-shadow: 2px 2px 2px 0px rgb(128 0 128 / 20%);
  overflow: auto;
}
/* 左侧拖拽元素样式 */
.title {
  font-size: 16px;
  font-weight: 500;
  width: 100%;
  margin: 10px 0 0 24px;
}
.item {
  display: flex;
  flex-direction: column;
  align-items: center;
  background: white;
  padding: 4px 10px;
  margin: 10px 8px 4px 8px;
  width: 38%;
  min-height: 60px;
  border-radius: 4px;
  box-shadow: 2px 2px 2px 2px rgba(171, 171, 171, 0.2);
}
.item .iconfont {
  font-size: 1.5rem;
}
.item span {
  font-size: 14px;
}

/* scrollbar */
::-webkit-scrollbar {
  height: 4px;
  width: 4px;
}
::-webkit-scrollbar-corner {
  height: 4px;
  width: 4px;
}
::-webkit-scrollbar-thumb {
  background: purple;
  border-radius: 2px;
  background-image: -webkit-linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.2) 25%,
    transparent 25%,
    transparent 50%,
    rgba(255, 255, 255, 0.2) 50%,
    rgba(255, 255, 255, 0.2) 75%,
    transparent 75%,
    transparent
  );
}
::-webkit-scrollbar-thumb:hover {
  background: purple;
}

/* flex */
.flex-row {
  display: flex;
}
.flex-col {
  display: flex;
  flex-direction: column;
}
.flex-wrap {
  flex-wrap: wrap;
}
.align-center {
  align-items: center;
}
.justify-center {
  justify-content: center;
}

.flex-1 {
  flex: 1;
}
.flex-2 {
  flex: 2;
}
.flex-3 {
  flex: 3;
}
.flex-4 {
  flex: 4;
}
.flex-5 {
  flex: 5;
}

.ml-10 {
  margin-left: 10px;
}
.mr-10 {
  margin-right: 10px;
}
.mt-10 {
  margin-top: 10px;
}
.mb-10 {
  margin-bottom: 10px;
}

button:hover {
  opacity: 1;
}
button i {
  font-size: 16px !important;
}
.circle,
.circle-4 {
  border-radius: 4px !important;
}
.circle-10 {
  border-radius: 10px !important;
}

/* modal */
.modal {
  padding: 0;
  margin: 0;
}
.modal .mask {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1000;
  height: 100%;
  background-color: #00000073;
}
.modal .wrap {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1000;
  overflow: auto;
  background-color: #00000073;
  outline: 0;
}
.modal .wrap .box {
  position: relative;
  margin: 10% auto;
  width: 40%;
  background: #fff;
  border-radius: 4px;
  z-index: 1001;
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
  transition: all 0.3s ease;
}
.modal-box__header {
  padding: 10px 14px;
  border-bottom: 1px solid #e9e9e9;
}
.modal-box__footer {
  text-align: end;
}
.modal-box__footer button {
  min-width: 100px;
}
.modal-box__footer button:not(:last-child) {
  margin-right: 10px;
}

拖拽组件

为了提供更加丰富的设计体验,可以通过自定义拖拽组件来增强打印模板设计器的功能性。例如,这里customProvider.js:可以添加个人业务(追溯业务)相关的元素,如文本、条形码、二维码等。

import { hiprint } from "vue-plugin-hiprint";
export const iCustomProvider = function (options) {
    console.log(options.moduleList.value);
    var addElementTypes = function (context) {
        context.removePrintElementTypes("providerModule1");
        context.addPrintElementTypes("providerModule1", [
            new hiprint.PrintElementTypeGroup("追溯业务", [
                // options.config,
                ...options.moduleList.value.map(item => ({
                    tid: item.defaultModule,
                    title: item.title,
                    data: item.title,
                    type: item.type,
                    options: {
                        field: item.field,
                        height: 14,
                        testData: "默认",
                        fontSize: 12,
                        fontWeight: '500',
                        textAlign: 'center',
                        textContentVerticalAlign: 'middle',
                        ...(item.textType ? { textType: item.textType } : {}),
                    },
                })),
                {
                    tid: "providerModule1.text",
                    title: "文本",
                    data: "文本",
                    type: "text",
                    options: {
                        field: "customText",
                        testData: "文本",
                        height: 14,
                        fontSize: 12,
                        fontWeight: "500",
                        textAlign: "left",
                        textContentVerticalAlign: "middle",
                    },
                },
                {
                    tid: "providerModule1.barcode",
                    title: "条形码",
                    data: "XS888888888",
                    type: "text",
                    options: {
                        field: "barcode",
                        testData: "XS888888888",
                        height: 32,
                        fontSize: 12,
                        lineHeight: 18,
                        textAlign: "left",
                        textType: "barcode",
                    },
                },
                {
                    tid: "providerModule1.qrcode",
                    title: "二维码",
                    data: "XS888888888",
                    type: "qrcode",
                    options: {
                        field: "qrcode",
                        testData: "XS888888888",
                        height: 32,
                        fontSize: 12,
                        lineHeight: 18,
                        textType: "qrcode",
                    },
                },
            ]),
        ]);
    };
    return {
        addElementTypes: addElementTypes,
    };
};

主组件调用

在主组件中,我们使用el-drawer来显示打印模板的设计界面,引入上述我们创建好的customProvider.js和。此界面包括纸张尺寸的选择或自定义输入,以及打印、导出模板为JSON格式的功能按钮。

<el-drawer v-model="drawer" title="创建模板" size="100%" @opened="buildDesigner">
  <!-- 纸张尺寸选择区域 -->
  <el-button-group>
    <el-button 
      v-for="(value, type) in paperTypes" 
      :key="type" 
      :type="getButtonType(type)" 
      @click="setPaper(type, value)">
      {{ type }}
    </el-button>
    <!-- 自定义纸张尺寸输入框 -->
    <el-popover 
      v-model="paperPopVisible" 
      title="设置纸张宽高(mm)" 
      :width="240" 
      trigger="click">
      <!-- 输入框 -->
      <el-input 
        type="number" 
        v-model="paperWidth" 
        placeholder="宽(mm)">
      </el-input>
      <el-input 
        type="number" 
        v-model="paperHeight" 
        placeholder="高(mm)">
      </el-input>
      <el-button type="primary" @click="otherPaper">确定</el-button>
    </el-popover>
  </el-button-group>

  <!-- 功能按钮 -->
  <button @click.stop="print"><i class="iconfont sv-printer" />浏览器打印</button>
  <button @click.stop="exportJson"><i class="iconfont sv-export" />保存模板</button>
  
  <!-- 其他元素 -->
  <div id="hiprint-printTemplate"></div>
</el-drawer>
<script setup name="Template" lang="ts">
import { hiprint } from 'vue-plugin-hiprint';
import { iCustomProvider } from './customProvider'
// ...
// 当前纸张
const curPaper = ref({
      type: 'other',
      width: 80,
      height: 60
    });
// 纸张类型
const paperTypes = ref({
    'A3': {
      width: 420,
      height: 296.6
    },
    'A4': {
      width: 210,
      height: 296.6
    },
    'A5': {
      width: 210,
      height: 147.6
    },
    'B3': {
      width: 500,
      height: 352.6
    },
    'B4': {
      width: 250,
      height: 352.6
    },
    'B5': {
      width: 250,
      height: 175.6
    }
  });
// 自定义纸张
const paperPopVisible = ref(false);
const paperWidth = ref('80');
const paperHeight = ref('60');
// 计算按钮类型
const getButtonType = (type) => {
  return curPaper.value.type === type ? 'primary' : 'default';
};
const drawer = ref(false);
/**
 * 构建左侧可拖拽元素
 * 注意: 可拖拽元素必须在 hiprint.init() 之后调用
 * 而且 必须包含 class="ep-draggable-item" 否则无法拖拽进设计器
 */
const buildLeftElement = () => {
  // eslint-disable-next-line no-undef
  // hiprint.PrintElementTypeManager.buildByHtml($(".ep-draggable-item"));

  $("#provider-container1").empty(); // 先清空, 避免重复构建
  // eslint-disable-next-line no-undef
  hiprint.PrintElementTypeManager.build($("#provider-container1"), "providerModule1");
};
/**
 * 构建设计器
 * 注意: 必须要在 onMounted 中去构建
 * 因为都是把元素挂载到对应容器中, 必须要先找到该容器
 */
let hiprintTemplate;
const buildDesigner = () => {
  //构建拖拽元素
  buildLeftElement();
  // eslint-disable-next-line no-undef
  $("#hiprint-printTemplate").empty(); // 先清空, 避免重复构建
  hiprintTemplate = new hiprint.PrintTemplate({
    settingContainer: "#PrintElementOptionSetting", // 元素参数容器
  });
  hiprintTemplate.design("#hiprint-printTemplate");
  if (data.form.templateJson) {
    mergeTemplate(data.form.templateJson);
  }
};

/**
 * 浏览器打印
 */
const print = () => {
  // 打印数据,key 对应 元素的 字段名
  let printData = { name: "CcSimple" };
  // 参数: 打印时设置 左偏移量,上偏移量
  let options = { leftOffset: -1, topOffset: -1 };
  // 扩展
  let ext = {
    callback: () => {
      console.log("浏览器打印窗口已打开");
    },
    styleHandler: () => {
      // 重写 文本 打印样式
      return "<style>.hiprint-printElement-text{color:red !important;}</style>";
    },
  };
  // 调用浏览器打印
  hiprintTemplate.print(printData, options, ext);
};
/**
 * 导出模板 json
 * 必须确保 hiprintTemplate 已成功创建
 */
const exportJson = () => {
  const jsonIns = hiprintTemplate.getJson();
  data.form.templateJson = JSON.stringify(jsonIns);
  drawer.value = false;
  validateTemplateJson();
};
/**
 * 导出模板 json tid
 * 仅导出 options, 不导出 printElementType
 * 必须确保 hiprintTemplate 已成功创建
 */
const exportJsonTid = () => {
  const jsonIns = hiprintTemplate.getJsonTid();
  console.log(jsonIns);
  alert("导出成功! 请查看控制台输出");
};
/**
 * 更新出新的模板内容
 */
const mergeTemplate = (jsonIn: string) => {
  if (hiprintTemplate) {
    try {
      hiprintTemplate.update(JSON.parse(jsonIn))
    } catch (e) {
      ElMessage.error(`更新失败: ${e}`)
    }
  }
};
/**
 * 设置纸张大小
 * @param type [A3, A4, A5, B3, B4, B5, other]
 * @param value {width,height} mm
 */
const setPaper = (type, value) => {
  try {
    // 更新当前纸张信息
    curPaper.value = {type: type, width: value.width, height: value.height};
    // 设置打印模板的纸张尺寸
    hiprintTemplate.setPaper(value.width, value.height);
  } catch (error) {
    ElMessage.error(`操作失败: ${error}`);
  }
};
  
// 触发模板数据的验证
const validateTemplateJson = () => {
  if (templateFormRef.value) {
    templateFormRef.value.validateField('templateJson').catch(() => { });
  }
};
/** 查询打印模板列表 */
const getList = async () => {
  loading.value = true;
  const res = await listTemplate(queryParams.value);
  templateList.value = res.rows;
  total.value = res.total;
  loading.value = false;
}
/** 获取模板组件数据 **/
let moduleList = ref([]);
const templateModules = async () => {
  try {
    const res = await getTemplateModule();
    moduleList.value = res.data.style;
  } catch (error) {
    console.error('Failed to fetch template module:', error);
  }
};
    
onMounted(async () => {
  getList();
  await templateModules();
  hiprint.init({
    providers: [iCustomProvider({ moduleList: moduleList })]
  });
  buildDesigner();
});
</script>
<style>
@import '@/assets/css/iconfont.css';
</style>

展示效果

在这里插入图片描述

注意事项

  1. 纸张尺寸自定义:在设置纸张尺寸时,需确保输入的数值符合实际打印设备支持的范围。
  2. 打印样式兼容性:不同浏览器对打印样式的处理可能略有差异,特别是在处理页面布局时,需要对特定浏览器进行针对性优化。
  3. 自定义元素类型:当添加自定义元素类型时,需确保每个元素的属性值正确无误,特别是对于条形码和二维码这样的复杂元素。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python如何导入模块及常见的导入方法

&#x1f600;前言 在 Python 编程中&#xff0c;模块&#xff08;Module&#xff09;是非常重要的工具。它们可以帮助我们将代码进行逻辑分割和复用&#xff0c;从而提高代码的可读性和可维护性。本文将详细介绍如何导入模块、使用常见的导入方法&#xff0c;并简要介绍一些常…

[分享] SQL在线编辑工具(好用)

在线SQL编写工具&#xff08;无广告&#xff09; - 在线SQL编写工具 - Web SQL - SQL在线编辑格式化 - WGCLOUD

若依微服务15 - RuoYi-Vue3 实现前端独立运行

正文开始&#xff1a; RuoYi-Vue3 使用 Vue3 Element Plus Vite 技术栈。 GitHub 开源地址&#xff1a;https://github.com/yangzongzhuan/RuoYi-Vue3 本文介绍使用若依提供的在线后端接口&#xff0c;仅启动前端项目并进行界面开发&#xff0c;而无需启动后端服务。 一、克隆…

Vue笔记-浏览器窗口改变时,重新计算表格高度并设置

当窗口大小改变时&#xff0c;你监听 window 对象的 resize 事件&#xff0c;然后在事件处理程序中重新计算表格的高度。在 Vue 中&#xff0c;可以在组件中通过 created 生命周期钩子来添加事件监听器&#xff0c;然后在组件销毁时移除事件监听器。 如下vue代码&#xff1a; …

33 类与对象 · 下

目录 一、构造函数的深入 &#xff08;一&#xff09;构造函数的其他特点 &#xff08;二&#xff09;使用例 1、Date类与Time类显示写 2、Date类与Time类写一部分 &#xff08;三&#xff09;总结 &#xff08;四&#xff09;初始化顺序小题目 二、类型转化 &#xff…

Linux Redis查询key与移除日常操作

维护老项目Express node 编写的后端程序、有这么一个方法、没有设置redis过期时间&#xff08;建议设置过期时间&#xff0c;毕竟登录生产服务器并不是每个人都有权限登录的&#xff01;&#xff01;&#xff01;&#xff09;。如果变动只能通过登录生产服务器、手动修改… 于…

@Autowired和@Resource的用法与区别

前言&#xff1a; Autowired 和 Resource 来自不同的“父类”&#xff0c;其中 Autowired 是 Spring 定义的注解&#xff0c;而 Resource 是 Java 定义的注解&#xff0c;它来自于 JSR-250&#xff08;Java 250 规范提案&#xff09;。当它们的实现类只有一个时&#xff0c;那…

github pages + hugo 搭建静态博客网站

体验地址 1. 起因&#xff0c; 目的: 其实6年前&#xff0c;我就写过这个。 项目代码 博客地址 最近想改写一下。 github 推荐的主题是 Jekyll&#xff0c; 我当时用的就是这个&#xff0c;感觉很麻烦。尤其是文章命名。 新的主题 hugo 用起来还行。 2.过程: 过程记录&am…

代码随想录算法训练营第六天|454四数相加II、 383赎金信、15三数之和、18四数之和

day06 1. 454四数相加II 首先定义 一个unordered_map&#xff0c;key放a和b两数之和&#xff0c;value 放a和b两数之和出现的次数。遍历大A和大B数组&#xff0c;统计两个数组元素之和&#xff0c;和出现的次数&#xff0c;放到map中。定义int变量count&#xff0c;用来统计 …

新电脑Win11家庭中文版跳过联网激活方法(教程)

预装Win11家庭中文版的新电脑&#xff0c;如何跳过联网激活&#xff1b;由于微软限制必须要联网激活&#xff0c;需要使用已有的微软账户登入或者注册新的微软账户后才可以继续开机使用&#xff0c;Win11联网后系统会自动激活。下面介绍一下初次开机初始化电脑时如何跳过联网激…

虚拟滚动列表如何实现?

highlight: a11y-dark 虚拟滚动列表&#xff0c;虚拟滚动的关键在于只渲染当前视口内可见的数据项&#xff0c;而不是一次性渲染所有数据项。这可以显著提高性能&#xff0c;尤其是在处理大量数据时。 以下是一个完整的虚拟滚动列表的示例代码&#xff1a; <!DOCTYPE htm…

RFC2616 超文本传输协议 HTTP/1.1

一、URL-俗称“网址” HTTP 使用 URL(Uniform Resource Locator&#xff0c;统一资源定位符)来定位资源&#xff0c;它是 URI(Uniform Resource Identifier&#xff0c;统一资源标识符)的子集&#xff0c;URL 在 URI 的基础上增加了定位能力 URI 除了包含 URL&#xff0c;还包…

ADC的交流参数

ADC的交流参数是衡量其在处理交流信号时性能的关键指标。一般包括&#xff1a; 1 信噪比&#xff08;Signal-to-Noise Ratio, SNR&#xff09; 这是衡量ADC输出信号中有用信号与噪声水平的比值。信噪比越高&#xff0c;表示ADC的性能越好。 SNR (dB) MaxRMSSignal / RMSNoise…

【你也能从零基础学会网站开发】 SQL Server结构化查询语言数据操作应用--DML篇 select语句数据查询操作详解 今天干货满满!《1024特别篇》

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;程序猿、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 select查询语句…

百度ocr服务自动实现文字识别、图片识别功能

百度ocr服务个人注册使用 介绍一个百度免费的ocr服务&#xff0c;通过调用SDK实现文字、图片识别等功能 1. 复制地址到自己的浏览器打开 https://cloud.baidu.com/doc/OCR/index.html2. 选择【登录】 3. 使用【短信登录】 4. 登录后需要选择【个人刷脸实名认证】 百度官方网…

第5.2章|25考研复试综合素质面试最常见问题50问【附上完整答案】超详细考研机械复试面试经验总结全流程 考研复试调剂问题看这一篇就够了!

接着上一章节的内容我们继续完善这50问的题目。上章节的内容参考这个文章。 第5.1章|25考研复试综合素质面试最常见问题50问【附上完整答案】超详细考研复试面试经验总结全流程 考研复试问题看这一篇就够了!考研复试调剂面试问题-CSDN博客https://blog.csdn.net/weixin_56510…

Linux基础命令(六)之 cut,sort,uniq,tr

目录 一&#xff0c;切割显示cut 参数及其作用 常见用法 二&#xff0c;排序显示sort 参数及其作用 常见用法 三&#xff0c;去重显示uniq 常见用法 四&#xff0c;替换文件中的字符显示tr 参数及其作用 常见用法 一&#xff0c;切割显示cut 用于按列提取文本内容 语…

Redis学习笔记(三)--Redis客户端

文章目录 一、命令行客户端二、图形界面客户端1、Redis Desktop Manager2、RedisPlus 三、java代码客户端 本文参考&#xff1a; Redis学习汇总&#xff08;已完结&#xff09; Redis超详细入门教程&#xff08;基础篇&#xff09; Redis视频从入门到高级&#xff0c;redis视频…

Text实现美团部分样式

Text基础 首先是Text的相关基础。 https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-text-0000001815927600 Text是显示一段文本的组件。 可以包含Span、ImageSpan、SymbolSpan和ContainerSpan子组件。 接口 Text(content?: string | …

基于SpringBoot设计模式之结构型设计模式·桥接模式

文章目录 介绍开始架构图定义类的功能定义类的实现 测试样例 总结 介绍 将抽象部分与它的实现部分分离&#xff0c;使他们都可以独立地发生变化。 Bridge的意思是桥梁。就像在现实世界中&#xff0c;桥梁的功能是将河流的两侧连接起来一样, Bridge模式的作用也是将两样东西连接…