【ArcGIS Pro二次开发】(74):Python、C#实现Excel截图导出图片

news2024/12/25 12:54:15

以村庄规划制图为例,通过对现状和规划用地的统计,生成Excel格式的【空间功能结构调整表】后,需要进一步将表格导出成图片,并嵌入到图集中,这样可以实现全流程不用手动参与,让制图的流程完全自动化。

关于Excel截图的方法,从python、c#都曾经历过,虽然有些方法已经不再用,但还是记录下来。

Excel表格如下:

导出的图片如下:

基本是完美的截图。


1、Python的截图方法

python里处理Excel的库不少,我使用的是PyWin32。

其它的库可能也能实现这个功能,但我没找到。

直接上代码:

import win32com.client as win32
from PIL import ImageGrab
import os

excel = win32.Dispatch('Excel.Application')
wb = excel.Workbooks.Open(excel_file)
ws = wb.WorkSheets(excel_tb)  # 打开工作簿

# 示例:截图的起始终止格
start_cell = "B2"
end_cell = "G8"

ws.Range(f"{start_cell}:{end_cell}").CopyPicture()  # 变成图片
ws.Paste(ws.Range(start_cell))  # 将图片黏贴在excel中

ws.Shapes(ws.Shapes.Count).Copy()  # 图片至剪贴板
img = ImageGrab.grabclipboard()  # 从剪贴板获取图片
img.save(output_png_path)  # 图片保存
wb.Save()  # excel保存
wb.Close()

这里的方法有曲折,相当于选定范围后,在Excel里CTRL+C,CTRL+V,然后再将粘贴后的图片复制出去。

2、C#的截图方法一:【Microsoft.Office.Interop.Excel】

【Microsoft.Office.Interop.Excel】库的功能非常强大,但它需要安装微软的Office才能使用,并且有兼容性和进程占用的问题,缺点也很明显。实际上这个方法之前也写过,这里复述一遍。

using Microsoft.Office.Interop.Excel;
using Application = Microsoft.Office.Interop.Excel.Application;
using Range = Microsoft.Office.Interop.Excel.Range;

// Excel指定范围导出JPG图片
public static void ExcelImportToJPG(string excelPath, string startRange, string endRange, string outputPath)
{
    // 在UI线程上执行添加item的操作
    System.Windows.Application.Current.Dispatcher.Invoke(() =>
    {
        // 例如:A1:G6
        string rangeAddress = startRange + ":" + endRange;

        // 创建Excel应用程序对象
        Application excelApp = new Application();
        // 打开Excel文件
        Workbook workbook = excelApp.Workbooks.Open(excelPath);
        // 获取工作表
        Worksheet worksheet = workbook.Sheets[1];
        // 获取范围对象
        Microsoft.Office.Interop.Excel.Range range = worksheet.Range[rangeAddress];
        // 获取范围的像素宽度和高度
        int widthInPixels = (int)Math.Round(range.Width * 1.3333);
        int heightInPixels = (int)Math.Round(range.Height * 1.3333);
        // 创建位图对象
        Bitmap bitmap = new Bitmap(widthInPixels, heightInPixels);
        // 将范围内容复制到剪贴板
        range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
        // 获取剪贴板图像数据
        System.Drawing.Image clipboardImage = null;
        if (System.Windows.Forms.Clipboard.ContainsImage())
        {
            clipboardImage = System.Windows.Forms.Clipboard.GetImage();

            // 在位图上绘制剪贴板图像
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                graphics.DrawImage(clipboardImage, 0, 0);
            }

            // 将位图保存为图片文件
            bitmap.Save(outputPath, ImageFormat.Jpeg); // 或者保存为PNG图片,将第二个参数改为ImageFormat.Png
        }

        // 关闭和释放资源
        workbook.Close(false);
        excelApp.Quit();
        System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);

        // 清空剪贴板数据
        System.Windows.Forms.Clipboard.Clear();
    });
}

3、C#的截图方法二:【Aspose.cells】

考虑到【Microsoft.Office.Interop.Excel】库的一些问题实在无法解决,后来选择了【Aspose.cells】库作为替代,那这个截图方法也得解决。

经网友【俊,】的帮助,【Aspose.cells】同样实现了这一方法,完美替代了【Microsoft.Office.Interop.Excel】。

代码如下:

using Aspose.Cells;
using Aspose.Cells.Rendering;

// Excel指定范围导出JPG图片
public static void ExcelImportToJPG(string excelPath, string Range, string outputPath)
{
    // 打开工作薄
    System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
    LoadOptions loadOptinos = new LoadOptions(LoadFormat.Xlsx);
    Workbook wb = new Workbook(excelPath, loadOptinos);
    // 打开工作表
    Worksheet sheet = wb.Worksheets[0];
    // 定义要截图的单元格范围   例:Range = "B2:G26"
    Range range = sheet.Cells.CreateRange(Range);
    // 设置打印属性
    ImageOrPrintOptions imgOptions = new ImageOrPrintOptions();
    // 在一页内打印
    imgOptions.OnePagePerSheet = true;
    // 只打印区域内
    imgOptions.OnlyArea = true;
    // 打印
    SheetRender render = new SheetRender(sheet, imgOptions);
    render.ToImage(0, outputPath);
    // 保存
    wb.Save(excelPath);
    wb.Dispose();
}

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

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

相关文章

系列十一、拦截器(二)#案例演示

一、案例演示 说明&#xff1a;如下案例通过springboot的方式演示拦截器是如何使用的&#xff0c;以获取Controller中的请求参数为切入点进行演示 1.1、前置准备工作 1.1.1、pom <dependencies><!-- spring-boot --><dependency><groupId>org.spring…

多模态最新经典论文合集,涵盖预训练、表征学习、多模态融合

最近多模态相关的论文好火&#xff0c;原因就不多说了&#xff08;懂得都懂&#xff09;&#xff0c;因为有不少想发paper的同学来问了&#xff0c;我就火速整理了一部分来和你们分享。 这次整理了6篇最新的多模态论文&#xff0c;还有12篇经典的文章&#xff0c;主要涉及预训…

优先级队列(堆)的概念+模拟堆的实现

文章目录 优先级队列&#xff08;堆&#xff09;的概念模拟堆的实现一、概念1.优先级队列2.堆1.堆的性质2.堆的存储3.堆的创建3.1 向下调整3.2建堆的时间复杂度 O(N) 4.堆的插入4.1向上调整4.2向上调整建堆的时间复杂度&#xff1a;O(N * log N) 5.堆的删除 优先级队列&#xf…

【Java 进阶篇】Java Session 原理及快速入门

大家好&#xff0c;欢迎来到本篇博客。今天&#xff0c;我们将探讨Java Web开发中一个重要而令人兴奋的概念&#xff0c;即Session&#xff08;会话&#xff09;。Session是一种在Web应用程序中跟踪用户状态和数据的机制。我们将深入了解Session的原理&#xff0c;并通过示例来…

LangChain+LLM实战---LlamaIndex、正确使用索引

LlamaIndex简介 LlamaIndex(也称为GPT Index)是一个用户友好的界面&#xff0c;它将您的外部数据连接到大型语言模型(Large Language Models, llm)。它提供了一系列工具来简化流程&#xff0c;包括可以与各种现有数据源和格式(如api、pdf、文档和SQL)集成的数据连接器。此外&a…

Android Studio(对话框AlertDialog)

前言 前面介绍了常用控件的相关属性&#xff0c;那些控件的使用起来也很容易。在本节及后面的章节介绍的控件将是相比于前面使用起来较为复杂的&#xff08;不过使用多了&#xff0c;也很容易上手&#xff09;。 这些控件常常需要配合java代码来使用&#xff0c;比如说对话框、…

如何将PDF文件转换成翻页电子书?这个网站告诉你

​随着电子书的普及&#xff0c;越来越多的人开始将PDF文件转换成翻页电子书。翻页电子书不仅方便阅读&#xff0c;而且还可以在手机上轻松翻页。那么如何将PDF文件转换成翻页电子书呢&#xff1f;今天就为大家介绍一个网站&#xff0c;可以帮助你轻松完成这个任务。 1.首先&am…

Redis-使用java代码操作Redis->java连接上redis,java操作redis的常见类型数据存储,redis中的项目应用

java连接上redisjava操作redis的常见类型数据存储redis中的项目应用 1.java连接上redis package com.zlj.ssm.redis;import redis.clients.jedis.Jedis;/*** author zlj* create 2023-11-03 19:27*/ public class Demo1 {public static void main(String[] args) { // …

语言的新启程之Solidity

官方网站 WTF-Solidity官网 编译器 区块链的基础 Gas 一经创建&#xff0c;每笔交易都收取一定数量的 gas&#xff0c;目的是限制执行交易所需要的工作量和为交易支付手续费。EVM 执行交易时&#xff0c;gas 将按特定规则逐渐耗尽。 gas price 是交易发送者设置的一个值&…

深入理解计算机系统CS213 - Lecture 02

Bits, Bytes, and Integer 1.位运算与条件运算 &&#xff0c;|&#xff0c;^&#xff0c;~ 是做位运算。诸位01运算。 &&&#xff0c;||&#xff0c;&#xff01;是判断条件真假&#xff0c;而后返回0或1。 2. 位移 x << y&#xff1a;左移y位&#xff…

Excel·VBA工作表导出为图片

《Excel转图片别再截图啦&#xff01;用这4个方法&#xff0c;高清且无损&#xff01;》&#xff0c;excel转为图片一般方法较为简单&#xff0c;那么能否使用vba将excel转为图片 选中区域导出为图片 zoom设置为2&#xff0c;导出图片较为清晰 Sub 选中区域导出为图片()Dim …

【iOS】——知乎日报第三周总结

文章目录 一、获取新闻额外信息二、工具栏按钮的布局三、评论区文字高度四、评论区长评论和短评论的数目显示五、评论区的cell布局问题和评论消息的判断 一、获取新闻额外信息 新闻额外信息的URL需要通过当前新闻的id来获取&#xff0c;所以我将所有的新闻放到一个数组中&…

MySQL基础『数据库基础』

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; MySQL 学习 &#x1f383;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 &#x1f381;软件版本&#xff1a; MySQL 5.7.44 文章目录 1.数据库概念1.1.什么是数据库1.2.数据库存储介质1.3.常见数据库 2.数…

【带头学C++】----- 三、指针章 ---- 3.5 字符串与指针

在 C 中&#xff0c;字符串可以通过指针来表示和操作。C 的字符串是由字符组成的字符数组&#xff0c;而指针则用于引用和操作内存中的数据。 1. 字符数组 1. 字符数组: 字符数组是最基本的字符串表示方式。可以使用字符数组来存储字符串&#xff0c;并使用指针来引用它。字符…

嵌入式中利用VS Code 远程开发原理

VS Code几乎是所有的程序员必备的工具之一&#xff0c;据说全球一般的开发者都使用过VS Code这款工具。 今天分享一篇 VS Code 实现远程办公相关的文章。 1、概 述 通常&#xff0c;我们都是每天到工作的办公室进行办公&#xff0c;但是&#xff0c;如果下班回家&#x…

Linux学习第32天:Linux INPUT 子系统实验(一):接纳

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 题目中用了“接纳”俩字。其实学习就是一个接纳的过程。接纳新的知识&#xff0c;从而转化为自己知识宝库的一部分。那今天学习的input子系统和今天的主题接纳有…

0基础2小时搭建自己的网站

​作者主页 &#x1f4da;lovewold少个r博客主页 ⚠️本文重点&#xff1a;0基础2小时搭建个人网站 &#x1f449;【C-C入门系列专栏】&#xff1a;博客文章专栏传送门 &#x1f604;每日一言&#xff1a;宁静是一片强大而治愈的神奇海洋&#xff01; 目录 前言 第一步 环境…

DETR 论文精读【论文精读】End-to-End Object Detection with Transformers

DETR 这篇论文&#xff0c;大家为什么喜欢它&#xff1f;为什么大家说它是一个目标检测里的里程碑式的工作&#xff1f;而且为什么说它是一个全新的架构&#xff1f; 大家好&#xff0c;今天我们来讲一篇 ECC V20 的关于目标检测的论文。它的名字想必大家都不陌生&#xff0c;也…

系列十二、过滤器 vs 拦截器

一、过滤器 vs 拦截器 1.1、区别 &#xff08;1&#xff09;触发时机不一样&#xff0c;过滤器是在请求进入容器后Servlet之前进行预处理的&#xff0c;请求结束返回也是&#xff0c;是在Servlet处理完后&#xff0c;返回给前端之前&#xff1b; &#xff08;2&#xff09;过滤…

5.3有效的括号(LC20-E)

算法&#xff1a; 题目中&#xff1a;左括号必须以正确的顺序闭合。意思是&#xff0c;最后出现的左括号&#xff08;对应着栈中的最后一个元素&#xff09;&#xff0c;应该先找到对应的闭合符号&#xff08;右括号&#xff09; 比如:s"( [ ) ]"就是False&#xf…