c#实现生成PDF的底层方法
在用uwp生成pdf的时候,发展此类类库有限,有的也需要钱,我最后实现pdf的底层方法生成pdf,代码如下
private async void GeneratePdf()
{ var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("uwpCSharp.pdf", Windows.Storage.CreationCollisionOption.ReplaceExisting);
using (var stream = await System.IO.WindowsRuntimeStorageExtensions.OpenStreamForWriteAsync(file))
{
using (var writer = new System.IO.StreamWriter(stream, System.Text.Encoding.UTF8))
{ List<long> xrefs = new List<long>();
writer.WriteLine("%PDF-1.2");
writer.Write("%");
writer.Flush();
byte[] bytes = { , , , };
stream.Write(bytes, , );
stream.Flush();
writer.WriteLine(""); writer.Flush();
stream.Flush();
xrefs.Add(stream.Position);
writer.WriteLine("1 0 obj");
writer.WriteLine("<<");
writer.WriteLine(" /Type /Catalog");
writer.WriteLine(" /Pages 2 0 R");
writer.WriteLine(">>");
writer.WriteLine("endobj"); // #2: 页面列表 - 我们只有一页文字
writer.Flush();
stream.Flush();
xrefs.Add(stream.Position);
writer.WriteLine("2 0 obj");
writer.WriteLine("<<");
writer.WriteLine(" /Type /Pages");
writer.WriteLine(" /Kids [3 0 R]");
writer.WriteLine(" /Count 1");
writer.WriteLine(">>");
writer.WriteLine("endobj"); // #3: 页面 - 这里放文字、资源等
writer.Flush();
stream.Flush();
xrefs.Add(stream.Position);
writer.WriteLine("3 0 obj");
writer.WriteLine("<<");
writer.WriteLine(" /Type /Page");
writer.WriteLine(" /Parent 2 0 R");
writer.WriteLine(" /MediaBox [0 0 612 792]");
// 默认的用户空间: 72/inch
writer.WriteLine(" /Resources");
writer.WriteLine(" <<");
writer.WriteLine(" /ProcSet [/PDF/Text]");
// 这个pdf只有文本
writer.WriteLine(" /Font");
writer.WriteLine(" <<");
writer.WriteLine(" /F0 4 0 R");
// 定义的三种字体, #4, #5 和 #6
writer.WriteLine(" /F1 5 0 R");
writer.WriteLine(" /F2 6 0 R");
writer.WriteLine(" >>");
writer.WriteLine(" >>");
writer.WriteLine(" /Contents 7 0 R");
writer.WriteLine(">>");
writer.WriteLine("endobj"); // #4, #5, #6: 三钟字体,我们使用pdf默认字体
//使用WinAnsi字符编码,定义如下
writer.Flush();
stream.Flush();
xrefs.Add(stream.Position);
writer.WriteLine("4 0 obj");
writer.WriteLine("<<");
writer.WriteLine(" /Type /Font");
writer.WriteLine(" /Subtype /Type1");
writer.WriteLine(" /Encoding /WinAnsiEncoding");
writer.WriteLine(" /BaseFont /Times-Roman");
writer.WriteLine(">>");
writer.Flush();
stream.Flush();
xrefs.Add(stream.Position);
writer.WriteLine("5 0 obj");
writer.WriteLine("<<");
writer.WriteLine(" /Type /Font");
writer.WriteLine(" /Subtype /Type1");
writer.WriteLine(" /Encoding /WinAnsiEncoding");
writer.WriteLine(" /BaseFont /Times-Bold");
writer.WriteLine(">>");
writer.Flush();
stream.Flush();
xrefs.Add(stream.Position);
writer.WriteLine("6 0 obj");
writer.WriteLine("<<");
writer.WriteLine(" /Type /Font");
writer.WriteLine(" /Subtype /Type1");
writer.WriteLine(" /Encoding /WinAnsiEncoding");
writer.WriteLine(" /BaseFont /Times-Italic");
writer.WriteLine(">>"); // #7:内容页面。这是用postscript编写的,
// 有兴趣的朋友可以查看PDF 1.2参考手册第8章
writer.Flush();
stream.Flush();
xrefs.Add(stream.Position);
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.AppendLine("BT");
// BT =开始文本对象
sb.AppendLine("/F0 30 Tf");
// Tf = 使用文字 "F0" 定义文字大小为 "30"
sb.AppendLine("30 TL");
// TL = 设置高度为 "30"
sb.AppendLine("140.0 780.0 Td");
// Td = 文本坐标的位置 "140.0", "780.0"
sb.AppendLine("1.0 0.0 0.6 rg");
// rg = 字体前景颜色设置
sb.AppendLine("(Microsoft Corporation India) '");
sb.AppendLine("ET"); //画线
//顶部的线
sb.AppendLine("BT");
sb.AppendLine("10 TL");
sb.AppendLine("50.0 730.0 Td");
sb.AppendLine("0.0 0.0 0.0 rg");
sb.AppendLine("(__________________________________)'");
sb.AppendLine("ET"); //左边
sb.AppendLine("BT");
sb.AppendLine("10 TL");
sb.AppendLine("47.0 703.0 Td");
sb.AppendLine("0.0 0.0 0.0 rg");
for (int i = ; i <= ; i++)
{
sb.AppendLine("(|)'");
}
sb.AppendLine("ET"); //中间的线
sb.AppendLine("BT");
sb.AppendLine("10 TL");
sb.AppendLine("240.0 703.0 Td");
sb.AppendLine("0.0 0.0 0.0 rg");
for (int i = ; i <= ; i++)
{
sb.AppendLine("(|)'");
}
sb.AppendLine("ET"); //画右边的线
sb.AppendLine("BT");
sb.AppendLine("10 TL");
sb.AppendLine("557.0 703.0 Td");
sb.AppendLine("0.0 0.0 0.0 rg");
for (int i = ; i <= ; i++)
{
sb.AppendLine("(|)'");
}
sb.AppendLine("ET"); //底部的线
sb.AppendLine("BT");
sb.AppendLine("10 TL");
sb.AppendLine("50.0 102.0 Td");
sb.AppendLine("0.0 0.0 0.0 rg");
sb.AppendLine("(__________________________________)'");
sb.AppendLine("ET"); //文字
sb.AppendLine("BT");
sb.AppendLine("/F0 15 Tf");
sb.AppendLine("20 TL");
sb.AppendLine("70.0 670.0 Td");
sb.AppendLine("0.0 0.2 1.0 rg");
sb.AppendLine("(Parameter1)'");
sb.AppendLine("ET");
//
sb.AppendLine("BT");
sb.AppendLine("/F0 15 Tf");
sb.AppendLine("20 TL");
sb.AppendLine("0.0 0.0 0.0 rg");
sb.AppendLine("260.0 670.0 Td");
sb.AppendLine("(test1) '");
sb.AppendLine("ET");
//
sb.AppendLine("BT");
sb.AppendLine("/F0 15 Tf");
sb.AppendLine("20 TL");
sb.AppendLine("0.0 0.2 1.0 rg");
sb.AppendLine("70.0 645.0 Td");
sb.AppendLine("(Parameter2)'");
sb.AppendLine("ET");
//
sb.AppendLine("BT");
sb.AppendLine("/F0 15 Tf");
sb.AppendLine("20 TL");
sb.AppendLine("0.0 0.0 0.0 rg");
sb.AppendLine("260.0 645.0 Td");
sb.AppendLine("(test2) '");
sb.AppendLine("ET");
//
sb.AppendLine("BT");
sb.AppendLine("/F0 15 Tf");
sb.AppendLine("20 TL");
sb.AppendLine("0.0 0.2 1.0 rg");
sb.AppendLine("70.0 615.0 Td");
sb.AppendLine("(Parameter3)'");
sb.AppendLine("ET");
//
sb.AppendLine("BT");
sb.AppendLine("/F0 15 Tf");
sb.AppendLine("20 TL");
sb.AppendLine("260.0 615.0 Td");
sb.AppendLine("0.0 0.0 0.0 rg");
sb.AppendLine("(test3) '");
//
//
sb.AppendLine("BT");
sb.AppendLine("/F0 15 Tf");
sb.AppendLine("20 TL");
sb.AppendLine("0.0 0.2 1.0 rg");
sb.AppendLine("70.0 575.0 Td");
sb.AppendLine("(Parameter4)'");
sb.AppendLine("ET");
//
sb.AppendLine("BT");
sb.AppendLine("/F0 15 Tf");
sb.AppendLine("20 TL");
sb.AppendLine("260.0 575.0 Td");
sb.AppendLine("0.0 0.0 0.0 rg");
sb.AppendLine("(test4) '");
sb.AppendLine("ET");
//
writer.WriteLine("7 0 obj");
writer.WriteLine("<<");
writer.WriteLine(" /Length " + sb.Length);
writer.WriteLine(">>");
writer.WriteLine("stream");
writer.Write(sb.ToString());
writer.WriteLine(" q");
writer.WriteLine(" 156 0 0 272 100 200 cm"); //[1 2 3 4 5 6 cm] translate to (5,6) and scale for 1
writer.WriteLine(" /Img1 Do");
writer.WriteLine(" Q");
writer.WriteLine("endstream");
writer.WriteLine("endobj"); writer.Flush();
stream.Flush();
dynamic xref_pos = stream.Position;
writer.WriteLine("xref");
writer.WriteLine("1 " + xrefs.Count);
long xref = ;
foreach (long xref_loopVariable in xrefs)
{
xref = xref_loopVariable;
writer.WriteLine("{0:0000000000} {1:00000} n", xref, );
} // PDF-TRAILER. PDF以这个节点结尾.
writer.WriteLine("trailer");
writer.WriteLine("<<");
writer.WriteLine(" /Size " + xrefs.Count);
writer.WriteLine(" /Root 1 0 R");
writer.WriteLine(">>");
writer.WriteLine("startxref");
writer.WriteLine(xref_pos);
writer.WriteLine("%%EOF");
}
} await Windows.System.Launcher.LaunchFileAsync(file);
}
c#实现生成PDF的底层方法的更多相关文章
- [.NET开发] C#使用doggleReport生成pdf报表的方法
本文实例讲述了C#使用doggleReport生成pdf报表的方法.分享给大家供大家参考,具体如下: 1. 安装nuget -install package DoddleReport -install ...
- [轉載]史上最强php生成pdf文件,html转pdf文件方法
之前有个客户需要把一些html页面生成pdf文件,然后我就找一些用php把html页面围成pdf文件的类.方法是可谓是找了很多很多,什么html2pdf,pdflib,FPDF这些都试过了,但是都没有 ...
- 史上最强php生成pdf文件,html转pdf文件方法
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- Django中生成PDF(一)
Django中生成PDF(一) 需求描述: 某网站与其用户达成一致的协议,每份协议中都有用户相关的独特信息,且还需要生成PDF并存档.PDF文件中需要有企业LOGO.文字描述等信息.其展现形式 ...
- js将 HTML 页面生成 PDF 并下载
最近碰到个需求,需要把当前页面生成 pdf,并下载.弄了几天,自己整理整理,记录下来,我觉得应该会有人需要 :) 先来科普两个插件: html2Canvas 简介 我们可以直接在浏览器端使用html2 ...
- Python数据生成pdf文件
sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...
- 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档
背景 在计量领域中,计量检定是一种重要形式,主要用于评定计量器具的计量性能,确定其量值是否准确一致,实现手段包括计量检验.出具检定证书和加封盖印等. 在检定证书这一环节,存在一个难点,就是无法在线预览 ...
- asp.net 生成PDF方法
今天转博客园看到有人发表了一篇生成PFd的文章,准备自己也留一份准备以后用到的时候方便调用: 首先去itextsharp网站下载控件(https://sourceforge.net/projects/ ...
- 在asp.net 中生成PDF的方法
近期要用asp.net 2.0生成PDF,看了下书,查了下资料,发现可以有组件帮得上忙,可以下载itextsharp(https://sourceforge.net/projects/itextsha ...
随机推荐
- Nmap-脚本检测CVE漏洞
Nmap的一个鲜为人知的部分是NSE,即Nmap Scripting Engine,这是Nmap最强大和最灵活的功能之一.它允许用户编写(和共享)简单脚本,以自动执行各种网络任务.Nmap内置了全面的 ...
- Joomla 3.4.6 RCE 分析
Joomla 3.4.6 RCE 漏洞分析,首发先知社区: https://xz.aliyun.com/t/6522 漏洞环境及利用 Joomla 3.4.6 : https://downloads. ...
- Laravel 5.8 RCE 分析
原帖地址 : https://xz.aliyun.com/t/6059 Laravel 代码审计 环境搭建 composer create-project --prefer-dist laravel/ ...
- Python 中取代 Printf 大法的工具
「printf 大法」大概是最早期学到的 debug 方式?不同语言有不同的指令,在 Python 里对应的是 print指令 (加上%或是.format). 刚刚看到「 cool-RR/pysnoo ...
- Java的自动装箱
JDK5的新特性自动装箱:把基本类型转换为包装类类型自动拆箱:把包装类类型转换为基本类型 注意一个小问题: 在使用时,Integer x = null;代码就会出现NullPointerExcepti ...
- $_FILES上传错误类型
$_FILES['file']['error']其值为 0,没有错误发生,文件上传成功. 其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值. 其值 ...
- sql注入学习笔记
1.什么是SQL注入 SQL注入就是指web应用程序对用户输入的数据的合法性没有判断,前端传入后端的参数带有数据库查询的语句,攻击者可以构造不同的SQL语句来实现对数据库的操作. 2.SQL注入原理 ...
- Playbook中标签的使用(五)
一个playbook文件中,执行时如果想执行某一个任务,那么可以给每个任务集进行打标签,这样在执行的时候可以通过-t选择指定标签执行, 还可以通过--skip-tags选择除了某个标签外全部执行等 [ ...
- 构造最短程序打印自身的 MD5
一,介绍 比赛题目很简单:构造一个程序,在 stdout 上打印出自身的 MD5,程序越短越好.按最终程序文件大小字节数排名,文件越小,排名越靠前. 只能使用 ld-linux-x86-64.so, ...
- Libra教程之:Libra协议的关键概念
文章目录 Libra协议 交易和状态 交易详解 账本状态详解 版本数据库 账户 账户地址 Proof 验证节点 存储 Libra协议 Libra协议是Libra区块链的基础,本文主要讲解Libra协议 ...