1、下载PDFlib,下面的链接下载的是破解版,否则有“hello pdflib”的水印。
地址:http://download.youkuaiyun.com/detail/qiantz/3032494
2、创建一个pdf:
char* name;
PDFlib *p;
name = "test.pdf"
output = fopen(name, "wb");
if(!output)
return FALSE;
try{
if(!p)
p = new PDFlib();
}
catch (PDFlib::Exception &ex){
return FALSE;
}
if(!p)
{
fclose(output);
return 0;
}
// This means we must check return values of load_font() etc.
p->set_parameter(L"errorpolicy",L"return");
p->begin_document_callback(get_buffer, L"destination={type=fitwindow} pagelayout=onecolumn flush=heavy");
创建一个pdf对象,错误处理策略为返回错误参数,不采取异常处理错误的方式。调用begin_document_callback开始生成一个PDF文档,当生成pdf数据时,使用get_buffer进行接收,有效避免多次写入磁盘,提升写入效率。
3、string 与wstring 之间的转换:
/*
string 转换为 wstring
*/
std::wstring c2w(const char *pc)
{
std::wstring val = L"";
if(NULL == pc)
{
return val;
}
//size_t size_of_ch = strlen(pc)*sizeof(char);
//size_t size_of_wc = get_wchar_size(pc);
size_t size_of_wc;
size_t destlen = mbstowcs(0,pc,0);
if (destlen ==(size_t)(-1))
{
return val;
}
size_of_wc = destlen+1;
wchar_t * pw = new wchar_t[size_of_wc];
mbstowcs(pw,pc,size_of_wc);
val = pw;
delete pw;
return val;
}
/*
wstring 转换为 string
*/
std::string w2c(const wchar_t * pw)
{
std::string val = "";
if(!pw)
{
return val;
}
size_t size= wcslen(pw)*sizeof(wchar_t);
char *pc = NULL;
if(!(pc = (char*)malloc(size)))
{
return val;
}
size_t destlen = wcstombs(pc,pw,size);
/*转换不为空时,返回值为-1。如果为空,返回值0*/
if (destlen ==(size_t)(0))
{
return val;
}
val = pc;
delete pc;
return val;
}
4、缓冲区处理:
size_t get_buffer(PDF *p, void *data, size_t size)
{
if(buf_len + size <= BUFFER_SIZE)
{
memcpy(pdfdata + buf_len, data, size);
buf_len += size;
}
else
{
int len;
int index;
index = 0;
len = buf_len + size - BUFFER_SIZE;
len = size - len;
memcpy(pdfdata + buf_len, data, len);
index += len;
fwrite(pdfdata,1,BUFFER_SIZE,output);
fflush(output);
len = size - len;
while(len > BUFFER_SIZE)
{
memcpy(pdfdata, (unsigned char*)data + index, BUFFER_SIZE);
fwrite(pdfdata,1,BUFFER_SIZE,output);
fflush(output);
len -= BUFFER_SIZE;
index += BUFFER_SIZE;
}
buf_len = len;
memcpy(pdfdata, (unsigned char*)data + index, buf_len);
}
return size;
}
将转换成pdf格式的数据存入缓冲区,当缓冲区满时,写入磁盘。
5、生成pdf数据:
//创建一个在内存中的bmp图像
const wstring imagefile = L"/pvf/image/new.bmp";
p->create_pvf(imagefile,data, len, L"");
//pdf打印分辨率
char buf[128] = {0};
sprintf(&buf[0], "dpi=%d", pdf_pdi);
std::wstring dpi = c2w(&buf[0]);
//pdf页面尺寸,这个是可以任意设置的,也可以设置为pdflib中制定的尺寸,如a4_width,参看pdflib.h这个文件
memset(&buf[0], 0, 128);
sprintf(&buf[0], "width=%d height=%d", page_width, page_height);
std::wstring size = c2w(&buf[0]);
//设置绘制文本,矩形大小,对齐方式,绘制方式等
memset(&buf[0], 0, 128);
sprintf(&buf[0], "boxsize={%d %d} position=center fontsize=%d fitmethod=clip", text_width, text_height, text_height);
std::wstring con = c2w(&buf[0]);
while(is_true())
{
//开始一页
p->begin_page_ext(0, 0, size);
//int font = p->load_font(L"Helvetica", L"unicode", L"");
//加载字体,字体名称,字符编码
int font = p->load_font(L"Arial", L"unicode", L"");
p->setfont(font, text_height);
int image;
std::wstring zzm;
//加载图像,可以加载内存中的,也可以是磁盘上的,这里加载内存中的
image = p->load_image(L"bmp", imagefile, L"");
if(image < 0)
{
//加载失败,结束本页
p->end_page_ext(L"");
continue;
}
//绘制图像,根据分辨率来计算绘制区域
p->fit_image(image, x, y, dpi);
//关边图像
p->close_image(image);
//绘制文本,最后一个参数是文本格式
p->fit_textline(text, x, y, con);
//结束一页
p->end_page_ext(L"");
};
//删除创建的内存图像
p->delete_pvf(imagefile);
//执行后续处理,结束文档,写缓存等
p->end_document(L"");
delete p;
p = NULL;
fwrite(pdfdata, 1, buf_len, output);
buf_len = 0;
fclose(output);
PDFlib库的使用问题,暂时写到这,PDFlib是个很强大的库,德国人编写,正版价格也很高,其中有pdf模板功能,很方便使用。
注:string 与wstring之间互换是参考别人博客,由于时间长了,忘记出处,敬请见谅。