1. 程式人生 > >win32,使用PDFlib生成PDF檔案

win32,使用PDFlib生成PDF檔案

1、下載PDFlib,下面的連結下載的是破解版,否則有“hello pdflib”的水印。

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之間互換是參考別人部落格,由於時間長了,忘記出處,敬請見諒。