1 Star 5 Fork 2

yiywain / PDF表格

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
PdfTableExport.cpp 14.27 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
#include "stdafx.h"
#include "PdfTableExport.h"
#include <algorithm>
namespace PDFExport
{
int CPdfTableExport::m_defSize = 25;
PointF RectF::GetLeftBottom(void)
{
PointF pointf;
pointf.x = left;
pointf.y = bottom;
return pointf;
}
float RectF::GetWidth(void)
{
return abs(right-left);
}
float RectF::GetHeight(void)
{
return abs(bottom - top);
}
CPdfTableExport::CPdfTableExport()
{
m_ColConst = 0;
m_specific = (1/0.65);
m_PageSize = HPDF_PAGE_SIZE_A4; //默认大小
m_PageDirection = HPDF_PAGE_PORTRAIT; //默认方向
}
CPdfTableExport::~CPdfTableExport()
{
}
CPdfTableExport::element::element()
{
IsPassivity = false;
x = 0;
y = 0;
Formats = GetDefFont();
}
CPdfTableExport::element &CPdfTableExport::element::SetValue(std::string &str, Format &Formats)
{
this->Text = str;
this->Formats = Formats;
return *this;
}
void RGBCOLOR::SetRGB(int R, int G, int B)
{
if (R > 1 || G > 1 || B > 1)
{
r = R==0?0:255 / R;
g = G == 0 ? 0 : 255 / G;
b = B == 0 ? 0 : 255 / B;
}
else
{
r = R;
g = G;
b = B;
}
flag = true;
return;
}
void CPdfTableExport::SetColConst(int ColConst)
{
//为空
if (m_list.size() != 0)
{
for (std::vector<element> &row : m_list)
{
element ele;
//列不够插入空列
while (row.size() < ColConst)
row.push_back(ele);
//列超出移除
while (row.size() > ColConst)
row.pop_back();
}
}
m_ColConst = ColConst;
m_ColWidth.resize(ColConst, GetDefWidth());
}
bool CPdfTableExport::InsertRow(int Low, int Col, std::string &Text, Format &Formats)
{
if (m_ColConst < Col+1)
SetColConst(Col+1);
//中间插入
std::list<std::vector<element>>::iterator it;
int n = 0;
for (it = m_list.begin(); it != m_list.end(); it++,n++)
{
if (n == Low)
{
std::vector<element> ment(Col+1);
ment[Col].SetValue(Text, Formats);
it=m_list.insert(it, ment);
break;
}
}
//末尾追加
if (it == m_list.end())
{
std::vector<element> ment(m_ColConst);
ment[Col].SetValue(Text, Formats);
m_list.push_back(ment);
}
m_RowHeight.resize(Low+1, GetDefHeight());
return true;
}
bool CPdfTableExport::InsertRow(int Low, int Col,const char *Text, Format &Formats)
{
std::string str = Text;
return InsertRow(Low, Col, str, Formats);
}
bool CPdfTableExport::AddRow(int Col, std::string &Text, Format &Formats)
{
return InsertRow(m_list.size(), Col, Text, Formats);
}
bool CPdfTableExport::AddRow(int Col, const char *Text, Format &Formats)
{
return InsertRow(m_list.size(), Col, Text, Formats);
}
bool CPdfTableExport::SetFont(int Low, int Col, Format &Formats)
{
std::list<std::vector<element>>::iterator it;
int n = 0;
for (it = m_list.begin(); it != m_list.end(); it++, n++)
{
if (n == Low)
{
(*it)[Col].Formats=Formats;
break;
}
}
return true;
}
bool CPdfTableExport::SetText(int Low, int Col, std::string &Text, Format &Formats)
{
if (Col+1 > m_ColConst)
SetColConst(Col+1);
std::list<std::vector<element>>::iterator it;
int n = 0;
for (it = m_list.begin(); it != m_list.end(); it++, n++)
{
if (n == Low)
{
(*it)[Col].Text = Text;
(*it)[Col].Formats = Formats;
break;
}
}
return true;
}
bool CPdfTableExport::SetText(int Low, int Col, const char *Text, Format &Formats)
{
std::string str = Text;
return SetText(Low, Col, str, Formats);
}
bool CPdfTableExport::AddText(int page, int x, int y, const char *Text, PointAlignment Alignment , Format &Formats)
{
TextObject t;
t.page = page;
t.x = x;
t.y = y;
t.text = Text;
t.format = Formats;
t.alignment = Alignment;
m_TextList.push_back(t);
return true;
}
bool CPdfTableExport::AddImage(int page, int x, int y, const char *ImagePath, PointAlignment Alignment , int cx, int cy)
{
ImageObject img;
img.rect.left = x;
img.rect.top = y;
img.rect.bottom = y + abs(cy);//cy==0?0:y + abs(cy);
img.rect.right = x + abs(cx); //cx==0?0:x + abs(cx);
img.page = page;
img.path = ImagePath;
img.alignment = Alignment;
m_ImageList.push_back(img);
return true;
}
void CPdfTableExport::SetDefTextSize(int size)
{
m_defSize = size;
}
bool CPdfTableExport::SetMerge(int Low, int Col, int width, int height)
{
//保证不能瞎几把合并 合并时不修改列
if (m_ColConst < Col + width)
return false;
//合并时可以添加行
while (Low + height>m_list.size())
{
std::string str;
InsertRow(Low, m_list.size(),str);
}
std::list<std::vector<element>>::iterator it;
int n = 0;
for (it = m_list.begin(); it != m_list.end() && n<Low + height; it++, n++)
{
if (n == Low)
{
//设置合并区域
(*it)[Col].IsPassivity=false;
(*it)[Col].x = width;
(*it)[Col].y = height;
}
//清空被合并区域
if (n >= Low&&n < Low + height)
{
for (int m = Col; m < Col + width; m++)
{
if (n != Low || m != Col) //嗷呜
{
(*it)[m].Text = "";
(*it)[m].IsPassivity = true;
//被合并的设置为合并的位置
(*it)[m].x = Low;
(*it)[m].y = Col;
}
}
}
}
return true;
}
//设置行高
void CPdfTableExport::SetRowHeight(int Row,float Height)
{
Height=fabsf(Height);
m_RowHeight[Row] = Height;
}
//设置范围行高 像素
void CPdfTableExport::SetRowRangeHeight(int Row, int Number, float Height)
{
std::fill(&m_RowHeight[Row], &m_RowHeight[Row+Number-1], Height);
}
//设置列宽
void CPdfTableExport::SetColWidth(int Col,float Width)
{
Width = fabsf(Width);
m_ColWidth[Col] = Width;
}
//设置范围列宽 像素
void CPdfTableExport::SetColRangeWidth(int Col, int Number, float Width)
{
std::fill(&m_ColWidth[Col], &m_ColWidth[Col + Number-1], Width);
}
//计算单个格子pos范围
RectF CPdfTableExport::GetElementRect(int Row, int Col, int BeginRow)
{
RectF rectf;
float x = m_BackGauge.left;
for (int i = 0; i < m_ColWidth.size() && i < Col; i++)
{
x += m_ColWidth[i];
}
rectf.left = x;
rectf.right = rectf.left + m_ColWidth[Col];
float y = m_BackGauge.top;
for (int i = BeginRow; i < m_RowHeight.size() && i < Row; i++)
{
y += m_RowHeight[i];
}
rectf.top = y;
rectf.bottom = rectf.top + m_RowHeight[Row];
return rectf;
}
//获取合并后的范围
RectF CPdfTableExport::GetMergeRect(element &ele, int Row, int Col, int BeginRow)
{
if (BeginRow > Row)
return RectF();
RectF rectf = GetElementRect(Row, Col, BeginRow);
if (!ele.IsPassivity&&ele.x>0 || ele.y > 0)
{
//修改单个边距为合并后的边距
rectf.bottom = rectf.top+ ele.y*m_RowHeight[Row];
rectf.right = rectf.left+ ele.x*m_ColWidth[Col];
}
return rectf;
}
//将原点为左上角坐标转换为左下角
void CPdfTableExport::TransformRectF(HPDF_Page &page, RectF &rect)
{
float y = HPDF_Page_GetHeight(page);
rect.top = y - rect.top;
rect.bottom = y - rect.bottom;
}
//将原点为左上角坐标转换为左下角
void CPdfTableExport::TransformPointF(HPDF_Page &page, PointF &pointf)
{
float y = HPDF_Page_GetHeight(page);
pointf.y = y - pointf.y;
}
PointF CPdfTableExport::GetAlignment(RectF &RectFs, PointAlignment Alignment)
{
PointF pointf;
switch (Alignment)
{
case PDFExport::TOP_LEFT_CORNER:
pointf.Setxy(RectFs.left, RectFs.bottom - RectFs.GetHeight());
break;
case PDFExport::LEFT_BOTTOM_CORNER:
pointf.Setxy(RectFs.left, RectFs.bottom);
break;
case PDFExport::TOP_RIGHT_CORNER:
pointf.Setxy(RectFs.left - RectFs.GetWidth(), RectFs.bottom - RectFs.GetHeight());
break;
case PDFExport::RIGHT_BOTTOM_CORNER:
pointf.Setxy(RectFs.left - RectFs.GetWidth(), RectFs.bottom);
break;
case PDFExport::CORNER:
pointf.Setxy(RectFs.left - RectFs.GetWidth() / 2, RectFs.bottom - RectFs.GetHeight() / 2);
break;
default:
break;
}
return pointf;
}
//以宽度为比例设置平分表格宽度
std::vector<float> CPdfTableExport::SetTableWidth(HPDF_Page &page)
{
float sum = 0;
int count = m_ColWidth.size();
for (float &f : m_ColWidth)
{
sum += f;
}
std::vector<float> widths;
RectF rectf=GetPageRect(page);
for (float &f : m_ColWidth)
{
float ff = rectf.GetWidth();
widths.push_back(rectf.GetWidth()*(f / sum));
}
return widths;
}
RectF CPdfTableExport::GetPageRect(HPDF_Page &page)
{
RectF rectf;
rectf.top = rectf.left=0;
rectf.bottom = HPDF_Page_GetHeight(page);
rectf.right = HPDF_Page_GetWidth(page);
rectf.top += m_BackGauge.top;
rectf.left += m_BackGauge.left;
rectf.bottom -= m_BackGauge.bottom;
rectf.right -= m_BackGauge.right;
return rectf;
}
//获取行高度
float CPdfTableExport::GetRowHeight(int begin, int end)
{
if (end < begin)
return 0;
float height=0;
for (int i = begin; i < end; i++)
{
height += m_RowHeight[i];
}
return height;
}
//增加页或查询页
HPDF_Page CPdfTableExport::GetPage(HPDF_Doc pdf, std::vector<HPDF_Page> &pages, int PageIndex)
{
if (PageIndex >= pages.size())
{
pages.push_back(HPDF_AddPage(pdf));
return pages.back();
}
return pages[PageIndex];
}
//设置表格边距
void CPdfTableExport::SetBackGauge(RectF rectf)
{
m_BackGauge = rectf;
}
void CPdfTableExport::SetBackGauge(float Left, float Top, float Right, float Bottom)
{
m_BackGauge.left = Left;
m_BackGauge.top = Top;
m_BackGauge.right = Right;
m_BackGauge.bottom = Bottom;
}
//设置页面大小和方向
void CPdfTableExport::SetPage(_HPDF_PageSizes PageSize, _HPDF_PageDirection PageDirection)
{
m_PageSize = PageSize;
m_PageDirection = PageDirection;
}
//生成PDF文档
int CPdfTableExport::SavePDF(const char *PDFPath)
{
HPDF_Doc pdf;
HPDF_Font font;
HPDF_Page page;
pdf = HPDF_New(nullptr, nullptr);
if (!pdf) {
return -1;
}
HPDF_SetCompressionMode(pdf, HPDF_COMP_ALL);
HPDF_STATUS status;
HPDF_UseCNSFonts(pdf);
HPDF_UseCNTFonts(pdf);
HPDF_UseCNSEncodings(pdf);
HPDF_UseCNTEncodings(pdf);
font = HPDF_GetFont(pdf, "SimSun", "GB-EUC-H");
std::vector<HPDF_Page> pages(1); //存储了所有页
pages[0] = HPDF_AddPage(pdf);
HPDF_Page_SetSize(pages[0], m_PageSize, m_PageDirection);//设置页
m_ColWidth = SetTableWidth(pages[0]); //设置表格宽度
page = pages[0];
//绘制表格文字
std::list<std::vector<element>>::iterator it;
int n = 0;
int PageBeginRow=0;//页首行
int PageIndex = 0;//当前页
//逐行
for (it = m_list.begin(); it != m_list.end(); it++, n++)
{
//新增页操作
if (GetRowHeight(PageBeginRow, n) + m_RowHeight[n]>GetPageRect(page).bottom)
{
HPDF_Page pagex;
pagex = HPDF_AddPage(pdf);
HPDF_Page_SetSize(pagex, m_PageSize, m_PageDirection);
m_ColWidth = SetTableWidth(pagex); //设置表格宽度
pages.push_back(pagex);
PageBeginRow = n;
page = pagex;
}
//逐列
for (int m = 0; m < it->size(); m++)
{
element *pEle = &(*it)[m];
if (pEle == nullptr)
break;
if (pEle->IsPassivity) //被合并的不绘制边框
continue;
//是否显示边框
if (pEle->Formats.Frame)
{
RectF rectf = GetMergeRect(*pEle, n, m, PageBeginRow);
TransformRectF(page, rectf);
status = HPDF_Page_SetLineWidth(page, 1);
status = HPDF_Page_SetRGBStroke(page, pEle->Formats.FrameColor.r, pEle->Formats.FrameColor.g, pEle->Formats.FrameColor.b);
if (pEle->Formats.FrameFillColor.flag)
status = HPDF_Page_SetRGBFill(page, pEle->Formats.FrameFillColor.r, pEle->Formats.FrameFillColor.g, pEle->Formats.FrameFillColor.b);
status = HPDF_Page_Rectangle(page, rectf.left, rectf.bottom, rectf.GetWidth(), rectf.GetHeight());
if (pEle->Formats.FrameFillColor.flag)
status = HPDF_Page_FillStroke(page);
else
status = HPDF_Page_Stroke(page);
}
}
}
//绘制表格边距线
n = 0;
page = pages[0];//设置为起始页
PageBeginRow = 0;
PageIndex = 0;
status = HPDF_Page_BeginText(page);
for (it = m_list.begin();it != m_list.end(); it++, n++)
{
//切换页
if (GetRowHeight(PageBeginRow, n) + m_RowHeight[n] > GetPageRect(page).bottom)
{
status = HPDF_Page_EndText(page);
page = pages[++PageIndex];
PageBeginRow = n;
status = HPDF_Page_BeginText(page);
}
//逐列
for (int m = 0; m < it->size(); m++)
{
float LowHeight = m_RowHeight[n]; //行高度
element *pEle = &(*it)[m];
if (pEle == nullptr)
break;
if (pEle->IsPassivity || pEle->Text.length() == 0)//被合并不绘制
continue;
//获取合并后的范围
RectF rectf = GetMergeRect(*pEle, n, m, PageBeginRow);
TransformRectF(page, rectf);
//保证文本显示完全 对字体大小做适配处理
float ActualHeight = 0;//实际使用高度
if (LowHeight<pEle->Formats.Size)
ActualHeight = LowHeight;
else
ActualHeight = pEle->Formats.Size;
status = HPDF_Page_SetFontAndSize(page, font, ActualHeight);
// float tw = HPDF_Page_TextWidth(page, pEle->Text.c_str());
status = HPDF_Page_SetRGBFill(page, pEle->Formats.TextColor.r, pEle->Formats.TextColor.g, pEle->Formats.TextColor.b);
status = HPDF_Page_TextRect(page, rectf.left, rectf.top, rectf.right, rectf.bottom, pEle->Text.c_str(), HPDF_TALIGN_CENTER, NULL);
}
}
status = HPDF_Page_EndText(page);
//绘制文本对象
m_TextList.sort();
int old_page_index=-1;
for (TextObject &t : m_TextList)
{
HPDF_Page page=GetPage(pdf, pages, t.page);
//单页执行一次
if (old_page_index!=t.page)
HPDF_Page_BeginText(page);
int h=HPDF_Page_GetHeight(page);
int w = HPDF_Page_GetWidth(page);
RectF rectf;
status = HPDF_Page_SetFontAndSize(page, font, t.format.Size);
float tw = HPDF_Page_TextWidth(page, t.text.c_str());
rectf.SetLeftBottom(t.x, t.y, tw, t.format.Size);
TransformRectF(page, rectf);
PointF po=GetAlignment(rectf, t.alignment);
status = HPDF_Page_SetRGBFill(page, t.format.FrameColor.r, t.format.FrameColor.g, t.format.FrameColor.b);
HPDF_Page_TextOut(page, po.x, po.y, t.text.c_str());
//单页执行一次
if (old_page_index != t.page)
{
HPDF_Page_EndText(page);
old_page_index = t.page;
}
}
//绘制图像对象
m_ImageList.sort();
for (ImageObject &t : m_ImageList)
{
HPDF_Page page = GetPage(pdf, pages, t.page);
HPDF_Image img = nullptr;
int n = t.path.rfind(".");
if (n > -1)
{
std::string Suffix = t.path.data()+n+1;
std::transform(Suffix.begin(), Suffix.end(), Suffix.begin(), ::tolower);
if (Suffix=="png")
{
img = HPDF_LoadPngImageFromFile(pdf, t.path.c_str());
}
else if (Suffix == "jpg" || Suffix == "jpeg" )
{
img = HPDF_LoadJpegImageFromFile(pdf,t.path.c_str());
}
if (img)
{
HPDF_Point point = HPDF_Image_GetSize(img);
RectF rectf = t.rect;
TransformRectF(page, rectf);
status = HPDF_Page_DrawImage(page, img, rectf.left, rectf.top, rectf.GetWidth()<1 ? point.x : rectf.GetWidth(), rectf.GetHeight()<1 ? point.y : rectf.GetHeight());
}
}
}
//test
//int w=HPDF_Page_GetWidth(pages[0]);
//int h= HPDF_Page_GetHeight(pages[0]);
//HPDF_Page_MoveTo(pages[0], 0, h/2);
//HPDF_Page_LineTo(pages[0], w, h/2);
//HPDF_Page_MoveTo(pages[0], w/2, 0);
//HPDF_Page_LineTo(pages[0], w/2, h);
//HPDF_Page_Stroke(pages[0]);
//test end
status=HPDF_SaveToFile(pdf, PDFPath);
HPDF_Free(pdf);
if (status)
return status;
return 0;
}
}
C++
1
https://gitee.com/yiywain/pdftable.git
git@gitee.com:yiywain/pdftable.git
yiywain
pdftable
PDF表格
master

搜索帮助