Vue 发送 PDF 文件链接到 WinForm 程序进行打印

Vue 发送 PDF 文件链接到 WinForm 程序进行打印的完整流程如下:

1. Vue 端

Vue 通过 fetchaxios 发送 PDF 文件的 URL 给 WinForms 程序(WinForms 需要开启一个本地 API)。

<template><div><button @click="sendPrintRequest">打印PDF</button></div>
</template><script>
import axios from "axios";export default {methods: {sendPrintRequest() {const pdfUrl = "http://yourserver.com/sample.pdf"; // 你的 PDF 地址axios.post("http://localhost:5000/print", { pdfUrl }) // 本地 WinForms 监听的 API.then((response) => {console.log("打印请求成功", response.data);}).catch((error) => {console.error("打印请求失败", error);});},},
};
</script>

2. WinForm 后端

WinForms 需要开启一个本地 HTTP 服务器,用于接收 Vue 发送的 PDF 链接,并调用本地打印机打印。

1) 创建一个 Web API

使用 HttpListener 监听 http://localhost:5000/print,并接收 Vue 发送的 JSON 数据。

using System;
using System.Drawing.Printing;
using System.IO;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Diagnostics;class Program
{static void Main(){HttpListener listener = new HttpListener();listener.Prefixes.Add("http://localhost:5000/"); // 监听本地端口listener.Start();Console.WriteLine("打印服务器已启动...");while (true){HttpListenerContext context = listener.GetContext();Task.Run(() => HandleRequest(context));}}static async void HandleRequest(HttpListenerContext context){HttpListenerRequest request = context.Request;HttpListenerResponse response = context.Response;if (request.HttpMethod == "POST" && request.Url.AbsolutePath == "/print"){using (StreamReader reader = new StreamReader(request.InputStream, request.ContentEncoding)){string requestBody = await reader.ReadToEndAsync();var data = JsonSerializer.Deserialize<PrintRequest>(requestBody);if (data != null && !string.IsNullOrEmpty(data.PdfUrl)){Console.WriteLine("收到打印请求:" + data.PdfUrl);bool success = PrintPdf(data.PdfUrl);response.StatusCode = success ? 200 : 500;string responseText = success ? "打印成功" : "打印失败";byte[] buffer = Encoding.UTF8.GetBytes(responseText);response.OutputStream.Write(buffer, 0, buffer.Length);}}}response.Close();}static bool PrintPdf(string pdfUrl){try{string localPath = Path.Combine(Path.GetTempPath(), "temp.pdf");using (WebClient client = new WebClient()){client.DownloadFile(pdfUrl, localPath);}ProcessStartInfo psi = new ProcessStartInfo{FileName = localPath,Verb = "print",CreateNoWindow = true,WindowStyle = ProcessWindowStyle.Hidden};Process.Start(psi);return true;}catch (Exception ex){Console.WriteLine("打印出错:" + ex.Message);return false;}}class PrintRequest{public string PdfUrl { get; set; }}
}
2) Aspose.Pdf 插件打印

复杂一点的,使用Aspose.Pdf打印插件进行答应

using Aspose.Pdf;
using PdfiumViewer;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing.Printing;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;namespace ConsoleApp1
{/// <summary>/// VUE发送PDF文件到客户端 客户端调用默认打印机 开始打印/// </summary>public class VueToPrintHelper{public VueToPrintHelper(){HttpListener listener = new HttpListener();listener.Prefixes.Add("http://localhost:5066/");listener.Start();Console.WriteLine("Listening for requests...");// 获取所有已安装的打印机foreach (string printer in PrinterSettings.InstalledPrinters){Console.WriteLine(printer);}while (true){HttpListenerContext context = listener.GetContext();Task.Run(() => HandleRequest(context));}}static async void HandleRequest(HttpListenerContext context){HttpListenerRequest request = context.Request;HttpListenerResponse response = context.Response;// 设置 CORS 头部,允许前端访问response.AddHeader("Access-Control-Allow-Origin", "*");response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");response.AddHeader("Access-Control-Allow-Headers", "Content-Type");// 处理 OPTIONS 预检请求 (CORS 预检)if (request.HttpMethod == "OPTIONS"){response.StatusCode = 200;response.Close();return;}if (request.HttpMethod == "POST" && request.Url.AbsolutePath == "/print"){using (StreamReader reader = new StreamReader(request.InputStream, request.ContentEncoding)){string requestBody = await reader.ReadToEndAsync();var data = JsonSerializer.Deserialize<PrintRequest>(requestBody);if (data != null && !string.IsNullOrEmpty(data.PdfUrl)){Console.WriteLine("收到打印请求:" + data.PdfUrl);bool success = PrintPdf(data.PdfUrl);response.StatusCode = success ? 200 : 500;string responseText = success ? "打印成功" : "打印失败";byte[] buffer = Encoding.UTF8.GetBytes(responseText);response.OutputStream.Write(buffer, 0, buffer.Length);}}}response.Close();}static bool PrintPdf(string pdfUrl){try{var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "print_pdfs");if (!Directory.Exists(filePath)){Directory.CreateDirectory(filePath);}string localPath = Path.Combine(filePath, Path.GetFileName(pdfUrl));if (!File.Exists(localPath)){using (WebClient client = new WebClient()){client.DownloadFile(pdfUrl, localPath);}}PrintPdf3(localPath);Console.WriteLine("打印命令已发送");return true;}catch (Exception ex){Console.WriteLine("打印出错:" + ex.Message);return false;}}static string DownloadPdf(string pdfUrl){string tempFilePath = Path.Combine(Path.GetTempPath(), "document.pdf");using (WebClient client = new WebClient()){try{client.DownloadFile(pdfUrl, tempFilePath);return tempFilePath;}catch (Exception ex){Console.WriteLine("Error downloading PDF: " + ex.Message);return null;}}}static void PrintPDF(string filePath){using (var document = PdfDocument.Load(filePath)) // 使用 PdfiumViewer 加载 PDF{PrintDocument printDocument = document.CreatePrintDocument();printDocument.Print();}}static void PrintPDF2(string filePath){ProcessStartInfo psi = new ProcessStartInfo{FileName = filePath,  // 这里直接是 PDF 文件Verb = "print",      // 使用默认应用程序打印UseShellExecute = true, // 关键:让 Windows 自动用默认应用打开CreateNoWindow = true,WindowStyle = ProcessWindowStyle.Hidden};Process.Start(psi);}static void PrintPdf3(string pdfPath){// 加载 PDF 文档Document pdfDocument = new Document(pdfPath);// 创建 PdfViewer 实例using (Aspose.Pdf.Facades.PdfViewer pdfViewer = new Aspose.Pdf.Facades.PdfViewer(pdfDocument)){pdfViewer.AutoResize = true;   // 自动调整大小pdfViewer.AutoRotate = true;   // 自动旋转pdfViewer.PrintPageDialog = false; // 不弹出打印对话框// 设置打印机Aspose.Pdf.Printing.PrinterSettings printerSettings = new Aspose.Pdf.Printing.PrinterSettings();printerSettings.PrinterName = PrinterSettings.InstalledPrinters[0]; // 选择默认打印机// 创建 PageSettings 并绑定 PrinterSettingsAspose.Pdf.Printing.PageSettings pageSettings = new Aspose.Pdf.Printing.PageSettings();pageSettings.PrinterSettings = printerSettings;// 进行打印pdfViewer.PrintDocumentWithSettings(pageSettings, printerSettings);}Console.WriteLine("✅ PDF 已发送到打印机!");}}class PrintRequest{public string PdfUrl { get; set; }}
}

3. 测试流程

  1. 运行 WinForms 程序,它会监听 http://localhost:5000/print
  2. Vue 页面点击按钮,发送 PDF URL 进行打印。
  3. WinForms 下载 PDF 并调用本地打印机 进行打印。

这种方式适用于局域网环境,Vue 只需要调用本地的 WinForms 服务器即可,不涉及复杂的文件传输流程。🎯

请求变成 OPTIONS,通常是由于 CORS 预检请求(Preflight Request)。当你从 Vue (浏览器) 发送 POST 请求到 http://localhost:5000/print,而此 API 位于 不同的端口,浏览器会先发送一个 OPTIONS 请求来检查服务器是否允许跨域访问。


解决方案

你需要在 WinForms API (C#) 中处理 OPTIONS 请求,返回适当的 CORS 头部,让浏览器允许跨域请求。

修改 C# 代码

HandleRequest 方法中添加对 OPTIONS 请求的处理:

static async void HandleRequest(HttpListenerContext context)
{HttpListenerRequest request = context.Request;HttpListenerResponse response = context.Response;// 处理 OPTIONS 预检请求 (CORS 预检)if (request.HttpMethod == "OPTIONS"){response.AddHeader("Access-Control-Allow-Origin", "*");response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");response.AddHeader("Access-Control-Allow-Headers", "Content-Type");response.StatusCode = 200;response.Close();return;}if (request.HttpMethod == "POST" && request.Url.AbsolutePath == "/print"){using (StreamReader reader = new StreamReader(request.InputStream, request.ContentEncoding)){string requestBody = await reader.ReadToEndAsync();var data = JsonSerializer.Deserialize<PrintRequest>(requestBody);if (data != null && !string.IsNullOrEmpty(data.PdfUrl)){Console.WriteLine("收到打印请求:" + data.PdfUrl);bool success = PrintPdf(data.PdfUrl);response.StatusCode = success ? 200 : 500;string responseText = success ? "打印成功" : "打印失败";byte[] buffer = Encoding.UTF8.GetBytes(responseText);response.OutputStream.Write(buffer, 0, buffer.Length);}}}// 添加 CORS 头部 (允许跨域请求)response.AddHeader("Access-Control-Allow-Origin", "*");response.Close();
}

解释

  1. CORS 预检请求 (OPTIONS) 处理

    • OPTIONS 请求是浏览器在 跨域请求 时自动发送的,用于检查服务器是否允许这个请求。
    • Access-Control-Allow-Origin: * 允许来自任何域的请求。
    • Access-Control-Allow-Methods: POST, GET, OPTIONS 允许前端发送 POST 请求。
    • Access-Control-Allow-Headers: Content-Type 允许发送 JSON 数据。
  2. 添加 CORS 头部

    • POST 处理完成后,仍然需要 返回 Access-Control-Allow-Origin: *,否则浏览器可能仍然拒绝请求。

Vue 端 (可选优化)

你也可以在 Vue 端的 axios 请求中 显式添加 Content-Type,避免某些情况下触发 OPTIONS 预检请求:

axios.post("http://localhost:5000/print", { pdfUrl: "http://yourserver.com/sample.pdf" },{headers: { "Content-Type": "application/json" }}
);

最终效果

  1. WinForms API 允许跨域请求,不会再被 OPTIONS 请求阻挡。
  2. Vue 可以正常发送 POST 请求,WinForms API 正常接收并打印 PDF 🎉。

这样,Vue 和 WinForm 端的通信就能顺利进行了!🚀

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

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

相关文章

从零到一:开发并上线一款极简记账本小程序的完整流程

从零到一&#xff1a;开发并上线一款极简记账本小程序的完整流程 目录 前言需求分析与功能设计 2.1 目标用户分析2.2 核心功能设计2.3 技术栈选择 开发环境搭建 3.1 微信开发者工具安装与配置3.2 项目初始化3.3 版本控制与协作工具 前端开发 4.1 页面结构与布局4.2 组件化开发…

对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,比较其各自的优势 , 基于 openEuler 构建 LVS-DR 群集。

对比 LVS 负载均衡群集的 NAT 模式和 DR 模式&#xff0c;比较其各自的优势 NAT模式的优势&#xff1a; 可以隐藏后端服务器的IP地址&#xff0c;提高了系统的安全性。 支持多个后端服务器共享同一个IP地址&#xff0c;提高了系统的可扩展性。 可以在负载均衡器和后端服务…

【操作系统】操作系统结构

内核 什么是内核&#xff1f; 内核作为应用程序连接硬件设备的桥梁&#xff0c;使得应用程序只需关心与内核交互&#xff0c;不用关心硬件细节。 内核有哪些能力呢&#xff1f; 内核是怎么工作的&#xff1f; Linux 的设计 MultiTask SMP ELF ELF 的意思是可执行文件链接格式…

缓存的介绍

相关面试题 &#xff1a; ● 为什么要用缓存&#xff1f; ● 本地缓存应该怎么做&#xff1f; ● 为什么要有分布式缓存?/为什么不直接用本地缓存? ● 为什么要用多级缓存&#xff1f; ● 多级缓存适合哪些业务场景&#xff1f; 缓存思想 空间换时间(索引&#xff0c;集群&a…

什么是弧形光源

工业检测中的弧形光源是一种专门设计用于机器视觉和自动化检测的照明设备,通常用于提供均匀、高对比度的照明,以增强图像采集质量,便于检测系统识别和分析目标物体的特征。以下是关于工业检测弧形光源的详细介绍: 特点 1均匀照明: 弧形设计能够提供均匀的漫反射光,减少阴…

[每日动态]科技新闻每日信息差2025年2月14日

### 2025年2月14日科技新闻每日信息差 #### 引言 在快速发展的科技领域&#xff0c;信息差是决定个人和企业竞争力的关键因素。2025年2月14日&#xff0c;全球科技界迎来了多项重要进展&#xff0c;从人工智能到量子计算&#xff0c;从医疗科技到太空探索&#xff0c;这些…

Go语言实现单例模式

单例模式 单例模式分为饿汉和懒汉模式&#xff0c;前者是在程序启动的时候就初始化一个单例对象&#xff0c;后者是使用到这个单例的时候&#xff0c;才会初始化一个单例对象。 饿汉模式 package mainimport "fmt"type Singleton struct { }var instance *Singleto…

zyNo.23

SQL注入漏洞 1.SQL语句基础知识 一个数据库由多个表空间组成&#xff0c;sql注入关系到关系型数据库&#xff0c;常见的关系型数据库有MySQL,Postgres,SQLServer,Oracle等 以Mysql为例&#xff0c;输入 mysql-u用户名-p密码 即可登录到MySQL交互式命令行界面。 既然是…

LeapMotion第2代 Unity示范代码(桌面开发)

一、官方地址&#xff1a; 官网&#xff1a;https://www.ultraleap.com/ 驱动下载&#xff1a;https://leap2.ultraleap.com/downloads/leap-motion-controller-2/ docs地址&#xff1a;https://docs.ultraleap.com/xr-and-tabletop/tabletop/unity/getting-started/index.html…

深入剖析推理模型:从DeepSeek R1看LLM推理能力构建与优化

著名 AI 研究者和博主 Sebastian Raschka 又更新博客了。原文地址&#xff1a;https://sebastianraschka.com/blog/2025/understanding-reasoning-llms.html。这一次&#xff0c;他将立足于 DeepSeek 技术报告&#xff0c;介绍用于构建推理模型的四种主要方法&#xff0c;也就是…

使用Cocos Creator制作“打砖块”小游戏:从零开始的详细教程

Cocos Creator是一款强大的游戏开发工具,特别适合2D游戏的开发。本文将以经典的“打砖块”小游戏为例,逐步讲解如何使用Cocos Creator实现这个游戏。我们将从项目创建、场景搭建、脚本编写到最终的游戏发布,详细讲解每一步的实现过程。 1. 环境准备 首先,确保你已经安装了…

vue3常见面试题

当然&#xff0c;以下是关于 Vue 3 的一些常见面试题及其答案&#xff1a; 1. Vue 3 相比 Vue 2 有哪些主要改进&#xff1f; 性能提升&#xff1a;Vue 3 在编译时做了更多的优化&#xff0c;比如静态提升&#xff08;hoisting static nodes&#xff09;、事件监听缓存等。更…

Ubuntu 22.04 LTS 安装MinerU

1. 检测是否已安装nvidia驱动 nvidia-smi 如果看到类似如下的信息&#xff0c;说明已经安装了nvidia驱动&#xff0c;可以跳过步骤2 Note CUDA Version 显示的版本号应 > 12.1&#xff0c;如显示的版本号小于12.1&#xff0c;请升级驱动 2. 安装驱动 如没有驱动&#…

DeepSeek 指导手册(入门到精通)

第⼀章&#xff1a;准备篇&#xff08;三分钟上手&#xff09;1.1 三分钟创建你的 AI 伙伴1.2 认识你的 AI 控制台 第二章&#xff1a;基础对话篇&#xff08;像交朋友⼀样学交流&#xff09;2.1 有效提问的五个黄金法则2.2 新手必学魔法指令 第三章&#xff1a;效率飞跃篇&…

MacOS使用PhpWebStudy搭建PHP开发环境

mac上的PHP开发环境搭建方式有很多, brew, docker, mamp等, 这里使用最近新出的工具PhpWebStudy来搭建mac上的php开发环境 安装 使用brew安装 brew install phpwebstudy 无法使用brew的话, 可以去官网下载最新版本安装 FlyEnv | Powerful Web Server and Environment Mana…

布隆过滤器的原理和应用场景,解决缓存穿透

一、布隆过滤器BloomFilter是什么 布隆过滤器BloomFilter是一种专门用来解决去重问题的高级数据结果。 实质就是一个大型位数组和几个不同的无偏hash函数&#xff0c;无偏表示分布均匀。由一个初值为零的bit数组和多个哈希函数组成&#xff0c;用来判断某个数据是否存在&…

macOs安装nvm

首先确定本机上没有安装nvm 如果之前安装过先卸载 1. 删除 nvm 目录 首先&#xff0c;删除 nvm 所安装的文件目录。默认情况下&#xff0c;nvm 会安装到 ~/.nvm 目录。 运行以下命令删除 nvm 目录&#xff1a; rm -rf ~/.nvm2. 移除 .zshrc 或 .bash_profile 中的 nvm 配置…

uniapp + vite + 使用多个 ui 库

样式冲突 新建了个项目 安装多个 ui 库 发现 uview-plus 和 Ant Design Vue 3.2.20 的 按钮样式 冲突uvuew-plus 的按钮样式 会被 ant 的样式给覆盖解决方式 找到圆满 ant.css 注释 button, html [type"button"], [type"reset"], [type"submit&quo…

【大语言模型】在大语言模型中,user、assistant、system 三种角色的定位和功能有何不同。

在大语言模型&#xff08;如GPT系列&#xff09;中&#xff0c;user、assistant、system 是三种核心角色&#xff0c;它们的定位和功能不同&#xff0c;共同构成对话的上下文结构。以下是具体区别和用途&#xff1a; 1. System&#xff08;系统角色&#xff09; 定位&#xff…

react中如何获取真实的dom

在 React 中&#xff0c;获取真实的 DOM 元素通常通过 ref 来实现。ref 是一个特殊的属性&#xff0c;用于引用组件或 DOM 元素的实例。你可以通过 ref 获取到组件的真实 DOM 元素或组件实例。 1. 函数组件中的 useRef 在函数组件中&#xff0c;获取 DOM 元素的引用需要使用 …