C#打造多功能PDF阅读器实战指南

部署运行你感兴趣的模型镜像

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本案例介绍了一个使用C#和.NET框架中的GDI+图形设备接口开发的PDF阅读器。阅读器能够提供流畅快速的用户体验,通过解析PDF文档内容并转化为屏幕上的像素。介绍了配置文件、资源文件、主要类文件和项目文件等关键组件,并说明了如何处理PDF格式的页面布局、字体、颜色和图像。该项目涵盖了文件处理、图形渲染和用户交互的各个方面,为开发者提供了深入学习C#编程、.NET框架以及PDF处理技术的机会。

1. C#编程语言与桌面应用开发

C#作为微软推出的一种优雅而功能强大的编程语言,凭借其简洁的语法和面向对象的特性,已经成为开发Windows桌面应用程序的首选语言之一。本章将带您走进C#的世界,探索其语言特性以及如何利用这些特性开发功能丰富的桌面应用。

首先,我们会介绍C#语言的基础,包括数据类型、控制流程以及面向对象编程的概念。接着,通过实例演示如何使用C#进行GUI开发,使用Windows Forms或WPF框架来创建用户友好的界面。最后,本章还会涉及一些C#高级主题,例如泛型、委托、事件以及LINQ查询,这些都是构建高效和可维护桌面应用程序不可或缺的要素。

通过学习本章内容,您将能够熟练运用C#进行桌面应用的开发,并掌握程序设计的核心技能,为后续更深入的.NET框架和GDI+图形处理等章节打下坚实的基础。

2. .NET框架和GDI+图形处理

2.1 .NET框架概述

.NET框架是微软开发的一个软件框架,它为应用程序提供了运行时环境。.NET框架的核心组件包括公共语言运行时(CLR)和一个庞大的框架类库(FCL)。C#是.NET框架下被广泛使用的一种编程语言,因其简洁性和面向对象的特性而受到开发者的青睐。

2.1.1 .NET框架的核心组件

.NET框架的核心组件是公共语言运行时(CLR)。CLR是一个软件组件,它负责管理代码执行、内存分配、异常处理以及安全性检查等。CLR提供了一个运行环境,允许开发者使用多种编程语言开发应用程序,并且可以将这些应用程序在不同的操作系统上运行,实现了语言之间的互操作性。.NET框架还包括一个丰富的框架类库(FCL),FCL提供了大量预制的类和接口,用于处理文件I/O、网络通信、数据库访问、图形界面、XML处理等常见任务。

2.1.2 C#在.NET框架中的应用

C#(读作“C Sharp”)是.NET框架下的官方编程语言。它是由微软设计并开发,作为一种简单、现代、面向对象且类型的强类型语言。C#的设计目标是结合Visual Basic的开发效率和C++的性能。C#提供了语言集成查询(LINQ)、异步编程等现代编程范式,并且通过CLR允许开发者使用.NET框架的功能。

2.2 GDI+图形处理基础

GDI+是.NET框架中处理图形和图像的一个子系统。GDI+提供了一系列丰富的API来绘制各种图形和图像,并且支持多种格式的图形文件。

2.2.1 GDI+图形对象模型

GDI+图形对象模型可以被描述为一个分层的结构,包括设备上下文(Graphics Device Interface,GDI)、绘图原语和高级绘图功能。设备上下文是所有GDI+图形操作的基础。GDI+支持绘制点、线、矩形、椭圆、曲线以及复杂的图形和图像,提供了强大的抗锯齿、透明度、渐变和图案填充等功能。

2.2.2 在C#中使用GDI+绘图

在C#中使用GDI+绘图,首先需要创建一个Graphics对象。可以通过窗体的Paint事件或者使用自定义的控件来获取Graphics对象。之后,可以利用GDI+提供的各种绘图方法,如DrawLine、DrawRectangle、FillEllipse等,来进行基本的绘图操作。下面是一个简单的代码示例,展示了如何在C#中使用GDI+绘制一个矩形:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    Graphics g = e.Graphics;
    Rectangle rect = new Rectangle(50, 50, 200, 100);
    g.FillRectangle(Brushes.Blue, rect);
    g.DrawRectangle(Pens.Black, rect);
}

在上述代码中,首先通过事件参数获取Graphics对象g,然后定义了一个矩形rect,使用蓝色填充并绘制边框。这是一个基础的操作,可以在此基础上进行更复杂的图形绘制。

2.2.3 GDI+的高级图形处理技术

GDI+不仅仅适用于简单的2D绘图,它还提供了高级图形处理技术,如图像处理、文本处理、透明度和复杂的颜色混合等。图像处理功能包括缩放、旋转、裁剪、颜色调整等。文本处理功能则支持复杂的文本排版、字体渲染和文本抗锯齿。透明度和颜色混合功能则允许开发者创建出视觉层次丰富且具有专业感的图形界面。

总结而言,.NET框架和GDI+是构建现代化应用程序不可或缺的部分。.NET框架为应用程序提供了一个可靠的运行环境和丰富的库支持,而GDI+则使得开发者能够在应用程序中实现复杂的图形处理需求。下一节将详细介绍PDF文档的渲染与展示技术。

3. PDF文档渲染与展示

随着数字化信息的不断增长,PDF(便携式文档格式)已经成为信息共享和交换的标准之一。PDF文档以其格式固定、跨平台兼容以及丰富的内容展示能力,被广泛用于电子文档、报表、电子书籍等多种场合。然而,在应用程序中展示PDF文档并不是一件简单的事情。本章将深入探讨如何在C#应用程序中有效地渲染和展示PDF文档,以及相关的交互式元素和注释的处理。

3.1 PDF文件格式简介

3.1.1 PDF文件结构分析

PDF文件格式是由Adobe公司开发的一种专门用于电子文档交换的标准格式。每个PDF文件都由多个部分组成,其中包括:

  • 文件头:包含PDF文件的标识符和版本号。
  • 体:包含文件的所有内容,包括页面内容、字体、图像等。
  • 交叉引用表:记录文档体中对象的引用信息。
  • 文件尾:包含交叉引用表的位置和文件的一些元数据。

PDF文件格式支持嵌入字体、图像、矢量图形以及多媒体内容,并能够保持原文件的布局和格式,使得文档在不同的设备和操作系统上可以以相同的方式进行展示。

3.1.2 PDF渲染技术概述

渲染PDF文档涉及到对PDF文件中的每个页面进行解析,并将内容转换为屏幕上可以显示的图形。PDF渲染技术可以分为两种主要类型:软件渲染和硬件渲染。

软件渲染依赖于CPU进行计算和渲染,不依赖于图形处理单元(GPU)的能力,适用于性能受限的设备,但可能会导致渲染速度较慢。

硬件渲染则利用GPU来加速渲染过程,这可以大大提高渲染速度,并减少CPU的负担。但在某些情况下,硬件加速可能不支持某些PDF特性,如复杂的透明度处理或自定义着色器。

3.2 PDF文档渲染实践

3.2.1 使用.NET PDF库进行渲染

要在.NET应用程序中渲染PDF文档,你可以使用如PdfiumViewer、iTextSharp或Pdfium.NET等第三方库。这些库封装了PDF渲染的核心功能,使得开发者能够更加容易地在应用程序中集成PDF文档的查看和操作功能。

以下是一个使用PdfiumViewer库渲染PDF文档的示例代码:

// 引用PdfiumViewer的命名空间
using PdfiumViewer;

// 初始化PDF文档
var document = PdfDocument.Load("example.pdf");

// 创建PDF视图控件
var pdfView = new PdfViewerControl();
pdfView.Dock = DockStyle.Fill;
pdfView.Document = document;

// 将PDF视图控件添加到窗体中
this.Controls.Add(pdfView);

// 从这里可以进行进一步的交互操作,如页面导航、放大缩小等

在上述代码中,首先加载了一个PDF文档,然后创建了一个PDF视图控件并将文档关联到该控件上。最后,这个控件被添加到窗体上供用户查看。

3.2.2 实现PDF页面的加载与显示

加载和显示PDF页面是一个多步骤的过程,涉及到页面的解析、渲染以及图像的显示。在.NET环境中,页面渲染通常被封装在PDF渲染库中,而开发者需要处理的是如何加载和展示这些渲染后的页面。

为了提高用户体验,通常会有异步加载和显示页面的需求。以下是一个异步加载PDF页面的示例代码:

public async Task LoadPageAsync(PdfDocument document, int pageNumber)
{
    // 为页面创建一个新的渲染任务
    var renderTask = document.Render(pageNumber, 800, 600);
    // 等待渲染任务完成
    await renderTask;

    // 将渲染的页面显示在界面上
    DisplayRenderedPage(renderTask.Result);
}

private void DisplayRenderedPage(PdfRenderedPage renderedPage)
{
    // 将渲染的页面转换为Bitmap
    var bitmap = renderedPage.CreateBitmap();

    // 将Bitmap设置到界面上的PictureBox控件中
    pictureBox1.Image = bitmap;
}

在这段代码中, LoadPageAsync 方法异步加载指定页面的渲染结果。渲染任务完成后, DisplayRenderedPage 方法负责将渲染结果转换为位图,并显示在窗体的PictureBox控件中。

3.2.3 交互式元素与注释的处理

PDF文档不仅仅包含静态文本和图形,它还支持交互式元素,如按钮、链接、表单字段以及注释。在应用程序中展示PDF文档时,处理这些交互式元素和注释对于提供完整的用户体验至关重要。

以处理PDF注释为例,以下是一个示例代码段:

public void LoadAnnotations(PdfDocument document)
{
    foreach (var page in document.Pages)
    {
        foreach (var annotation in page.Annotations)
        {
            // 根据注释类型执行相应的处理逻辑
            switch (annotation.Type)
            {
                case PdfAnnotationType.Text:
                    ProcessTextAnnotation(annotation);
                    break;
                case PdfAnnotationType.Link:
                    ProcessLinkAnnotation(annotation);
                    break;
                // 其他注释类型的处理...
            }
        }
    }
}

private void ProcessTextAnnotation(PdfAnnotation annotation)
{
    // 提取文本注释的内容
    var text = annotation.Contents;

    // 展示文本注释,例如在界面上显示注释内容
    MessageBox.Show(text);
}

private void ProcessLinkAnnotation(PdfAnnotation annotation)
{
    // 获取链接注释的URL
    var uri = new Uri(annotation.Uri);

    // 打开链接,例如使用默认浏览器打开链接
    System.Diagnostics.Process.Start(uri.ToString());
}

在这段代码中,首先遍历PDF文档的每一页及其上的所有注释。对于每种类型的注释,根据其类型执行特定的处理逻辑。在上述例子中,文本注释通过弹窗展示,而链接注释则打开相应的网页。

处理交互式元素和注释时,需要对不同类型的元素采取不同的策略。例如,按钮元素可能需要绑定事件处理器以响应用户的点击,而表单字段可能需要提供填写和提交数据的功能。

通过以上章节内容的介绍,我们可以看到,在.NET应用程序中渲染和展示PDF文档是一个涉及多个层面的过程,需要对PDF文件格式有深刻的理解,同时还需要掌握相关的.NET库来实现渲染逻辑。此外,处理文档中的交互元素和注释也是提高用户交互体验的关键。接下来的章节将继续深入讨论应用程序配置与设置,为应用程序的优化和个性化提供支持。

4. 应用程序配置与设置

应用程序的配置与设置是软件开发中至关重要的一个环节,它不仅关系到软件的可用性和灵活性,还直接影响到用户体验。配置文件提供了一种方便的方式来管理应用程序的各种设置,使得软件的部署和维护更加高效。在本章节中,我们将深入探讨应用程序配置机制,并指导您如何实现用户个性化设置。

4.1 应用程序配置机制

应用程序配置机制允许开发者和用户通过简单的修改配置文件来调整应用程序的行为,而无需重新编译程序。配置文件通常是文本格式,便于阅读和编辑。

4.1.1 配置文件的作用与结构

配置文件在应用程序中扮演着存储运行时参数的角色,这些参数可以是用户设置的偏好、应用程序行为的开关,或者是软件环境的特定设置。

最常见的配置文件格式是XML(可扩展标记语言),因为它具有良好的可读性和易于处理的特点。一个典型的.NET应用程序配置文件(app.config)的结构如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="SettingName" value="SettingValue"/>
  </appSettings>
  <connectionStrings>
    <add name="DBConnection" connectionString="Data Source=Server;Initial Catalog=Database;Integrated Security=True"/>
  </connectionStrings>
</configuration>

在这个示例中, appSettings 部分用于存放各种应用程序设置,而 connectionStrings 部分则用于存储数据库连接字符串等敏感信息。

4.1.2 动态读写应用程序设置

在.NET应用程序中,可以使用 System.Configuration 命名空间下的类库来实现对配置文件的动态读写操作。以下是一个简单的代码示例,展示了如何读取和设置配置文件中的值:

using System;
using System.Configuration;

class Program
{
    static void Main()
    {
        // 读取配置文件中的设置项
        string settingValue = ConfigurationManager.AppSettings["SettingName"];
        Console.WriteLine("The setting value is: " + settingValue);

        // 修改配置文件中的设置项
        ConfigurationManager.AppSettings["SettingName"] = "NewValue";

        // 保存对配置文件的更改
        Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        config.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection("appSettings");
    }
}

在上述代码中,我们首先通过 ConfigurationManager.AppSettings 读取了名为”SettingName”的配置项。接着,我们修改了该配置项的值,并通过 ConfigurationManager.OpenExeConfiguration Configuration.Save 方法将更改保存回配置文件。

4.2 用户个性化设置

用户个性化设置允许应用程序根据用户的偏好调整其行为或外观,从而提供更贴近用户需求的功能和体验。

4.2.1 用户界面偏好设置

在用户界面(UI)方面,个性化设置可能包括颜色主题、布局调整、快捷键绑定等。开发者可以将这些设置保存在配置文件中,然后在应用程序启动时读取这些设置,并根据设置调整UI。

4.2.2 常见的用户自定义功能实现

用户自定义功能通常涉及到更复杂的配置需求,比如用户可以定义快捷操作、报表模板或者软件行为的参数调整等。实现这类功能需要开发者提供一个用户界面,让用户能够方便地进行设置,并将这些设置存储到配置文件中。

比如,一个支持用户自定义报表的应用程序可能会让用户选择需要显示的字段,并将这些选择保存在配置文件中。然后在运行时,应用程序读取这些设置来构建相应的报表。

<appSettings>
  <add key="CustomReportFields" value="Name, Age, Occupation"/>
</appSettings>

然后在应用程序中,开发者可以根据这个配置项来生成报表:

string reportFields = ConfigurationManager.AppSettings["CustomReportFields"];
Console.WriteLine("Generating custom report with fields: " + reportFields);
// 这里可以添加代码来实际生成报表

在以上代码示例中,用户自定义的报表字段被保存在配置文件中,并在应用程序中被读取以生成报表。

通过本章节的介绍,您应该对应用程序配置与设置有了更深入的理解。接下来的章节将进一步探讨如何通过配置机制优化界面设计和用户体验。

5. 界面设计与用户交互

5.1 WPF界面设计基础

WPF(Windows Presentation Foundation)是微软推出的一种用于构建Windows客户端应用程序的用户界面框架。它提供了一种全新的方式来创建和呈现用户界面,使得开发者可以利用XAML(可扩展应用程序标记语言)来声明式地构建界面。

5.1.1 WPF界面元素与布局

在WPF中,界面是由各种元素组合而成的,包括窗口(Window)、控件(Control)、文本框(TextBox)、按钮(Button)等。这些元素可以在XAML中进行声明,并通过C#代码进行逻辑绑定。

布局是指在WPF中元素的位置和尺寸是如何安排的。常用的布局容器有:

  • Canvas :绝对定位元素。
  • StackPanel :层叠元素,可以设置水平或垂直方向。
  • Grid :网格布局,可以通过定义行和列来精确控制元素位置。
  • WrapPanel :允许元素排列成行,当一行满时自动换行。
  • ** dockPanel**:允许元素停靠到父容器的边缘。

布局容器可以嵌套使用,以创建复杂的布局。

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel Margin="10" Orientation="Horizontal">
            <Button Content="Button1" Width="75"/>
            <Button Content="Button2" Width="75"/>
            <Button Content="Button3" Width="75"/>
        </StackPanel>
        <TextBox Height="50" Width="200" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="20"/>
    </Grid>
</Window>

5.1.2 数据绑定与样式设计

数据绑定是WPF中一个非常重要的概念,允许开发者将界面元素与数据源连接起来。这样,当数据源中的数据发生变化时,界面元素会自动更新。数据绑定使用 {Binding} 表达式,并可以通过指定 Source Path 属性来指定数据源和数据路径。

<TextBox Text="{Binding Path=UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

样式(Style)设计允许开发者定义如何显示一个控件,包括字体、颜色、边距等属性。样式可以应用于单个控件,也可以定义为资源被多个控件共享。

<Window.Resources>
    <Style x:Key="myButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="Blue"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="FontSize" Value="12"/>
    </Style>
</Window.Resources>

<Button Style="{StaticResource myButtonStyle}" Content="Click Me"/>

5.2 用户交互与体验优化

用户交互是应用程序设计中一个至关重要的方面。WPF提供了一个强大的事件处理系统和命令模式来响应用户的动作。

5.2.1 事件驱动与命令模式

事件驱动是指应用程序响应用户的动作(如点击按钮、按键等)而执行特定的代码。WPF支持C#中的事件处理方式,开发者可以为控件添加事件处理器来响应事件。

private void Button_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Button clicked!");
}

命令模式提供了一种更高级的方式来处理用户输入。它允许将命令逻辑与触发命令的控件分离。在WPF中, ICommand 接口及其两个主要实现 RelayCommand DelegateCommand 被广泛用于MVVM(Model-View-ViewModel)模式中。

5.2.2 实现高效用户交互流程

为了实现高效的用户交互流程,开发者应该遵循一些最佳实践,比如:

  • 尽量减少每个界面的复杂性,避免过多的信息一次性展示给用户。
  • 使用模式和对话框来提示用户进行关键决策。
  • 对用户的操作进行反馈,如使用动画和声音提示。
  • 提供撤销/重做、复制/粘贴等用户习惯的操作支持。

使用MVVM模式可以将业务逻辑(ViewModel)和用户界面(View)分离开来,这不仅有助于代码的管理,还可以提升应用的性能和可测试性。

// ViewModel示例
public class MainViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _userName;
    public string UserName
    {
        get => _userName;
        set
        {
            _userName = value;
            OnPropertyChanged(nameof(UserName));
        }
    }

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

为了达到高效用户交互流程的目的,开发者应该利用这些WPF特性,结合具体应用场景设计和优化用户界面。通过不断的测试与用户反馈,改进产品的可用性和体验。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本案例介绍了一个使用C#和.NET框架中的GDI+图形设备接口开发的PDF阅读器。阅读器能够提供流畅快速的用户体验,通过解析PDF文档内容并转化为屏幕上的像素。介绍了配置文件、资源文件、主要类文件和项目文件等关键组件,并说明了如何处理PDF格式的页面布局、字体、颜色和图像。该项目涵盖了文件处理、图形渲染和用户交互的各个方面,为开发者提供了深入学习C#编程、.NET框架以及PDF处理技术的机会。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

C#实现生成PDF文档(附源码) 收藏 //write by wenhui.org using System; using System.IO; using System.Text; using System.Collections; namespace PDFGenerator { public class PDFGenerator { static float pageWidth = 594.0f; static float pageDepth = 828.0f; static float pageMargin = 30.0f; static float fontSize = 20.0f; static float leadSize = 10.0f; static StreamWriter pPDF=new StreamWriter("E:\myPDF.pdf"); static MemoryStream mPDF= new MemoryStream(); static void ConvertToByteAndAddtoStream(string strMsg) { Byte[] buffer=null; buffer=ASCIIEncoding.ASCII.GetBytes(strMsg); mPDF.Write(buffer,0,buffer.Length); buffer=null; } static string xRefFormatting(long xValue) { string strMsg =xValue.ToString(); int iLen=strMsg.Length; if (iLen<10) { StringBuilder s=new StringBuilder(); int i=10-iLen; s.Append('0',i); strMsg=s.ToString() + strMsg; } return strMsg; } static void Main(string[] args) { ArrayList xRefs=new ArrayList(); //Byte[] buffer=null; float yPos =0f; long streamStart=0; long streamEnd=0; long streamLen =0; string strPDFMessage=null; //PDF文档头信息 strPDFMessage="%PDF-1.1 "; ConvertToByteAndAddtoStream(strPDFMessage); xRefs.Add(mPDF.Length); strPDFMessage="1 0 obj "; ConvertToByteAndAddtoStream(strPDFMessage); strPDFMessage="<> "; ConvertToByteAndAddtoStream(strPDFMessage); strPDFMessage="stream "; ConvertToByteAndAddtoStream(strPDFMessage); ////////PDF文档描述 streamStart=mPDF.Length; //字体 strPDFMessage="BT /F0 " + fontSize +" Tf "; ConvertToByteAndAddtoStream(strPDFMessage); //PDF文档实体高度 yPos = pageDepth - pageMargin; strPDFMessage=pageMargin + " " + yPos +" Td " ; ConvertToByteAndAddtoStream(strPDFMessage); strPDFMessage= leadSize+" TL " ; ConvertToByteAndAddtoStream(strPDFMessage); //实体内容 strPDFMessage= "(http://www.wenhui.org)Tj " ; ConvertToByteAndAddtoStream(strPDFMessage); strPDFMessage= "ET "; ConvertToByteAndAddtoStream(strPDFMessage); streamEnd=mPDF.Length; streamLen=streamEnd-streamStart; strPDFMessage= "endstream endobj "; ConvertToByteAndAddtoStream(strPDFMessage); //PDF文档的版本信息 xRefs.Add(mPDF.Length); strPDFMessage="2 0 obj "+ streamLen + " endobj "; ConvertToByteAndAddtoStream(strPDFMessage); xRefs.Add(mPDF.Length); strPDFMessage="3 0 obj <> endobj "; ConvertToByteAndAddtoStream(strPDFMessage); xRefs.Add(mPDF.Length); strPDFMessage="4 0 obj <</Type /Pages /Count 1 "; ConvertToByteAndAddtoStream(strPDFMessage); strPDFMessage="/Kids[ 3 0 R ] "; ConvertToByteAndAddtoStream(strPDFMessage); strPDFMessage="/Resources<</ProcSet[/PDF/Text]/Font<> >> "; ConvertToByteAndAddtoStream(strPDFMessage); strPDFMessage="/MediaBox [ 0 0 "+ pageWidth + " " + pageDepth + " ] >> endobj "; ConvertToByteAndAddtoStream(strPDFMessage); xRefs.Add(mPDF.Length); strPDFMessage="5 0 obj <> endobj "; ConvertToByteAndAddtoStream(strPDFMessage); xRefs.Add(mPDF.Length); strPDFMessage="6 0 obj <> endobj "; ConvertToByteAndAddtoStream(strPDFMessage); streamStart=mPDF.Length; strPDFMessage="xref 0 7 0000000000 65535 f "; for(int i=0;i<xRefs.Count;i++) { strPDFMessage+=xRefFormatting((long) xRefs[i])+" 00000 n "; } ConvertToByteAndAddtoStream(strPDFMessage); strPDFMessage="trailer <> "; ConvertToByteAndAddtoStream(strPDFMessage); strPDFMessage="startxref " + streamStart+" %%EOF "; ConvertToByteAndAddtoStream(strPDFMessage); mPDF.WriteTo(pPDF.BaseStream); mPDF.Close(); pPDF.Close(); } } }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值