DevExpress(WinForms WPF)中文教程 - 如何减小文档文件大小?

DevExpress拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress近期重要版本v24.1已正式发布,该版本拥有众多新产品和数十个具有高影响力的功能,可为桌面、Web和移动应用提供直观的解决方案,全面解决各种使用场景问题。

减小文档文件大小可以改善文档导入/处理相关操作,它还可以帮助最小化数据库和云服务器中的文件存储需求。在这篇文章中,我们将使用DevExpress(WinForms & WPF) Word Processing API来减少Microsoft Word文档文件大小的不同策略。

重要提示:下面列出的策略涉及删除文档内容,删除的内容将无法恢复。

获取DevExpress v24.1正式版下载(Q技术交流:532598169)

简化文档

虽然显而易见,文档简化是减少/优化文件大小的最佳方法,简化策略包括:

  • 在可能的情况下,使用一组有限的样式来格式化文档内容。
  • 将文档从DOCM格式转换为DOCX格式来消除宏,您也可以使用RichEditDocumentServer.Options.DocumentCapabilities.Macros 选项来禁用宏。
  • 在保存文档之前禁用跟踪更改,RichEditDocumentServer包含RichEditDocumentServer.Options.DocumentCapabilities.TrackChanges属性用于禁用跟踪。
  • 减少图像内容。
  • 使用链接OLE对象代替嵌入OLE对象,如果无法使用链接的OLE对象,可以减小嵌入OLE对象的大小或在保存之前将其删除。有关OLE对象支持的其他信息,请参阅以下文章:OLE Objects in Word Documents
  • 减少字段和内容控件的使用,在保存之前取消链接或删除字段。
  • 用压缩图像替换图表。
  • 删除额外的元数据(XML数据、文档属性、注释、RTF主题数据)。
  • 将长表划分为多个短表,在大多数情况下,长表不会影响文件大小,但会减慢文档呈现和布局计算。
使用OpenXML格式替代传统格式

OpenXML格式(DOCX)是现代的、开放的、跨多个平台兼容的,虽然在某些情况下更有效,但遗留格式(如DOC、RTF)是专有的,灵活性较差。OpenXML文件本质上是带有XML文件和附加资源(如图像和样式)的ZIP存档,因此DOCX文件更容易存储在数据库中,您可以使用RichEditDocumentServer.Save 方法将文档转换为所需的文件格式。

不要嵌入字体

DevExpress Word Processing Document API允许您在文档中嵌入字体,虽然具有嵌入式字体的文档在不同的计算设备上保持外观特征,但这些文档的大小要大得多。如果您的解决方案在受控/托管环境中显示文档,我们建议使用DevExpress DXFontRepository类。有关更多信息,请参阅以下帮助主题:Load and Use Custom Fonts Without Installation on the System

减小图像大小

您可以使用第三方应用程序来压缩文档图像,一旦压缩,只需要调用PictureFormat.SetPicture方法将原始图像替换为其压缩后的等效图像。

下面的代码片段将原始图像替换为压缩后的等效图像:

using (RichEditDocumentServer wordProcessor = new RichEditDocumentServer()) {
wordProcessor.LoadDocument("doc_with_images.docx");
Document document = wordProcessor.Document;
Shape shape = document.Shapes[0];
DXImage sourceImage = shape.PictureFormat.Picture.DXImage;
MemoryStream imageStream = new MemoryStream();
sourceImage.Save(stream);
//Compress the image saved in the stream
//...
DXImage compressedImage = DXImage.FromStream(updatedImageStream);
shape.PictureFormat.SetPicture(compressedImage);
}

另一个技巧是不要裁剪图像,使用保存的预裁剪版本。您可以使用PictureFormat.SourceRect属性在代码中裁剪图像,然后保存输出,PictureFormatSetPicture方法允许您将图像替换为裁剪后的版本。

下面的代码片段裁剪图像,保存它,然后用裁剪后的等效图像替换原始图像:

using (RichEditDocumentServer wordProcessor = new RichEditDocumentServer()) {
wordProcessor.LoadDocument("CroppedImages.docx");
Document document = wordProcessor.Document;
Shape shape = document.Shapes[0];
if (shape.PictureFormat != null) {
DXBitmap image = shape.PictureFormat.Picture.DXImage as DXBitmap;
var rectOffset = shape.PictureFormat.SourceRect;
RectangleF imageRect = new RectangleF(image.Width * rectOffset.LeftOffset,
image.Height * rectOffset.TopOffset,
image.Width - image.Width * rectOffset.LeftOffset - image.Width * rectOffset.RightOffset,
image.Height - image.Height * rectOffset.TopOffset - image.Height * rectOffset.BottomOffset);
MemoryStream imageStream = new MemoryStream();
image.Crop(imageRect).Save(imageStream, image.ImageFormat);
DocumentImageSource source = DocumentImageSource.FromStream(imageStream);
shape.PictureFormat.SetPicture(source);
shape.PictureFormat.SourceRect = new RectangleOffset();
}
}

如果需要使用大图像,并且应用程序架构允许您单独存储图像,则可以采用以下解决方案。迭代文档的形状集合,并将所有图像保存到具有唯一标识符的数据库中。完成后,用空图像或DOCVARIABLE字段(用于动态图像替换)替换原始文档图像,或者删除图像并用书签标记其在文档中的位置。通过使用此策略,您将能够保存文档的轻量级版本,并在必要时恢复原始文档图像:

Document document = wordProcessor.Document;
// iterate through document images, save them to the database
// and replace original images with an empty image
int imageID = 1; // generate an image ID as you require
DocumentImageSource emptyImageSource = DocumentImageSource.FromImage(new DXBitmap(1, 1));
for (int i = document.Shapes.Count - 1; i >= 0; i--)
{
Shape shape = document.Shapes[i];
if (shape.PictureFormat != null)
{
DXBitmap image = shape.PictureFormat.Picture.DXImage as DXBitmap;
using (MemoryStream imageStream = new MemoryStream()) {
image.Save(imageStream, image.ImageFormat);
byte[] imageBytes = imageStream.ToArray();
// save image bytes to the database with the specified image ID
// ...
// change the image name (if required) to identify it later
shape.Name = "Image " + imageID.ToString();
// replace the current image with the empty image
shape.PictureFormat.SetPicture(emptyImageSource);
}
imageID++;
}
}
// save the document with dummy images
using (MemoryStream documentStream = new MemoryStream())
document.SaveDocument(documentStream, DocumentFormat.OpenXml);//...
// restore document images
richEditControl.LoadDocument(documentStream, DocumentFormat.OpenXml);
Document document = richEditControl.Document;
for (int i = document.Shapes.Count - 1; i >= 0; i--)
{
Shape shape = document.Shapes[i];
if (shape.PictureFormat != null)
{
string imageName = shape.Name;
// extract the required image from the database by name
byte[] imageBytes = ...;
using(MemoryStream imageStream = new MemoryStream(imageBytes))
{
// replace the empty image with the original image
DocumentImageSource imageSource = DocumentImageSource.FromStream(imageStream);
shape.PictureFormat.SetPicture(imageSource);
}
}
}

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

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

相关文章

PlugLink 与 AI 大模型:深入 COZE API 链接实践(附源码)

在这个技术日新月异的时代,AI 不再是遥不可及的概念,而是逐渐成为我们日常生活与工作中不可或缺的一部分。作为技术领域的探路者,我深感荣幸地向大家介绍 PlugLink —— 一个旨在简化 AI 应用集成并促进跨领域协作的开源平台,以及…

开源数字人项目Hallo

硬件条件: gpu最低12G 软件: cuda需支持 Python选择3.10吧,我的版本3.11 源码: GitHub - fudan-generative-vision/hallo: Hallo: Hierarchical Audio-Driven Visual Synthesis for Portrait Image Animation models文件&…

阅读笔记——《Fuzz4All: Universal Fuzzing with Large Language Models》

【参考文献】Xia C S, Paltenghi M, Le Tian J, et al. Fuzz4all: Universal fuzzing with large language models[C]//Proceedings of the IEEE/ACM 46th International Conference on Software Engineering. 2024: 1-13.【注】本文仅为作者个人学习笔记,如有冒犯&…

android paddingStart paddingLeft 使用区别

在 Android 开发中,paddingStart 和 paddingLeft 都是用来设置视图的内边距,但它们有一些重要的区别,尤其是在处理国际化和不同的布局方向(LTR 和 RTL)时: paddingLeft: 设置视图内容左侧的内边距。只在从左…

科研绘图系列:python语言实验线图(line Chart)

介绍 两组数据在不同时间点的差异检验结果线图 导入包 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from scipy import stats输入数据 ctr = [2, 2, 3, 3, 4, 5, 5, 6, 4, 8, 6, 6, 9, 11, 12, 12, 15, 16, 20, 25, 27] drug = [2, 3, …

python开发prometheus exporter--用于hadoop-yarn监控

首先写python的exporter需要知道Prometheus提供4种类型Metrics 分别是:Counter, Gauge, Summary和Histogram * Counter可以增长,并且在程序重启的时候会被重设为0,常被用于任务个数,总处理时间,错误个数等只增不减的指…

查看wsl 版本

要查看Windows Subsystem for Linux (WSL) 的版本,您通常需要查看WSL的版本号以及正在运行的Linux发行版的版本。以下是检查这两个版本的方法: 1. 查看WSL的版本(WSL 1 或 WSL 2) 要检查您的计算机上是否启用了WSL 2&#xff0c…

如何录制屏幕视频?4款软件,轻松录屏

在数字化飞速发展的时代,如何录制屏幕视频已经成为我们工作、学习和娱乐中不可省略的一个重要问题。无论是制作教学教程还是录制游戏视频等,屏幕视频录制都为我们提供了极大的便利。今天,就让我们一起探索如何录制屏幕视频的精彩方式&#xf…

多数据源配置导致注解Transactional失效

多数据源配置时,向事务管理器中注入数据源时可以直接注入DynamicRoutingDataSource而不要注入ItemDataSource类型,否则可能会出现事务失效问题。 其他事务失效问题参考: 注解Transaction踩坑指南 注解Transaction失效场景

Windows环境+C#实现显示接口测试

代码如下: using Models; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO; …

大模型“聚会”:国内卷价格,国外卷能力

[ GPT-4o和谷歌Gemini不断宣传现阶段AI能力大幅度提高,那么这两家,谁的大模型能力更强呢?这篇文章里,作者就展开了多维度的测试和体验,想了解的同学,可以来看一下。 在中美AI大模型的竞争上,正衍…

从数据仓库到数据湖(上):数据湖导论

文章目录 一、什么是数据湖?起源数据湖的特征 二、为什么要用数据湖?三、数据湖与数据仓库的区别数据仓库和数据湖的对比 四、数据湖本质数据存储架构数据处理工具:三类第一类工具第二类工具第三类工具 小结 五、总结六、参考资料 一、什么是…

[运维平台]泛微运维平台

运维平台点击登录没有反应,是因为H2数据库损坏,H2数据库在服务器异常重启,磁盘满等情况下容易损坏,请按照下面的步骤操作Linux: 运维平台升级包https://www.weaver.com.cn/cs/monitorDownload.html 1)请停…

常见数据库类型和选取详解

数据库是用于存储、检索和管理数据的系统。它们可以根据数据模型的不同被分类为不同类型。以下是一些常见的数据库类型和它们的选取详解: 1. 关系型数据库(RDBMS) 特点: 使用表格(tables)来组织数据。基…

百日筑基第十六天-java多线程编程浅学一下4-各种线程池学习和使用

百日筑基第十六天-java多线程编程浅学一下4-各种线程池学习和使用 使用线程池 Java语言虽然内置了多线程支持,启动一个新线程非常方便,但是,创建线程需要操作系统资源(线程资源,栈空间等),频繁…

MQ四兄弟:如何保证消息顺序性

在当今的分布式系统架构中,消息队列(MQ)是不可或缺的组成部分。它们在确保系统组件之间高效通信方面发挥着关键作用。特别是在金融交易、物流跟踪等对消息处理顺序有严格要求的场景中,消息队列的顺序性保证显得更为重要。接下来&a…

使用libguestfs挂载qcow2磁盘镜像

挂载qcow2磁盘镜像的第一种方法是使用 libguestfs,它提供了一系列工具来访问和编辑 VM 磁盘镜像。libguestfs 支持几乎所有类型的磁盘镜像,包括 qcow2。你可以像下面这样,在Linux上安装libguestfs工具集。 1、安装guestmount工具 在基于 De…

主干网络篇 | YOLOv5/v7 更换骨干网络之 MobileNetV3 | 基于神经网络搜索的轻量级网络(2)

主干网络篇 | YOLOv5/v7 更换骨干网络之 MobileNetV3 | 基于神经网络搜索的轻量级网络 概述 YOLOv5和YOLOv7是目前主流的轻量级目标检测模型,在速度和精度方面取得了良好的平衡。然而,传统的YOLOv5/v7模型使用FPN和CSPNet等结构作为主干网络&#xff0…

SMU Summer 2024 Contest Round 2

[ABC357C] Sierpinski carpet - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路:通过因为图形的生成过程是完全一样的。可以通过递归,不断分形。函数process(x,y,k)定义为以坐标(x,y)为左上角,填充sqrt3(k)级的地毯。 int n; int c[800][800]; 默认全为…

【杂说咋说】近年来国土空间规划行业人员转行分析

这几年,国土空间规划行业的人员流动引起了不少关注。我们可以从几个方面来看这些变化: 考公务员 许多从事国土空间规划的专业人员选择了考公务员。这种选择相对稳定,不需要熬夜加班,工作环境也更为舒适。尤其是进入国家机关或住…