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 ...
随机推荐
- CTFHub web技能树之RCE初步 命令注入+过滤cat
在一个大佬的突然丢了个题过来,于是去玩了玩rce的两道题 大佬的博客跳转链接在此->>>大佬召唤机 叫 命令注入 一上来就是源码出现,上面有个ping的地方 <?php $re ...
- TensorFlow命令行参数FLAGS使用
import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import tensorflow as tf #tensorboard --logdir=&qu ...
- 为什么redis是单线程的以及为什么这么快?
官网的说法 我们先来认真看一下官网的说法.翻译过来大意如下: CPU并不是您使用Redis的瓶颈,因为通常Redis要么受内存限制,要么受网络限制.例如,使用在一般Linux系统上运行的流水线Redi ...
- 前端面试题之HTML和css-很实用的知识点
display: none; 与 visibility: hidden; 的区别 相同: 它们都能让元素不可见 区别: display:none;会让元素完全从渲染树中消失,渲染的时候不占据任何空间: ...
- Configure Visual Studio with UNIX end of lines
As OP states "File > Advanced Save Options", select Unix Line Endings. https://stackove ...
- docker容器介绍
Docker容器 一.什么是Docker? Docker时Docker.Lnc公司开源的一个基于LXC技术之上搭建的Container容器引擎,源代码托管在Git ...
- XEP-0198:流管理
------------恢复内容开始------------ 原文来自:https://xmpp.org/extensions/xep-0198.html,只翻译了技术方面的内容. 摘要:这个规范定义 ...
- 【已解决】React项目中按需引入ant-design报错TypeError: injectBabelPlugin is not a function
react项目中ant-design按需加载,使用react-app-rewired的时候报错 运行npm start或者yarn start报如下错误: TypeError: injectBabel ...
- RxJava--Buffer,GroupBy 对比
Buffer 设定收集n个元素为一组,以下方代码为例,三个为一组,则当组满三个元素时,返回一次List数据 没组满三个元素时,如果调用onComplete,直接发送剩余元素,没调用onComplete ...
- TensorFlow框架 入门笔记
背景 略 基础 介绍 略 TensorFlow安装 link TensorFlow 主要概念 使用图(graph)来表示计算任务(执行流程). 在被称之为会话(session)的上下文(context ...