win32,使用PDFlib生成PDF檔案
阿新 • • 發佈:2019-02-20
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之間互換是參考別人部落格,由於時間長了,忘記出處,敬請見諒。