赞
踩
关于android端动态生成PDF文档的方案我也找了很多第三方的库,其中很多库对于安卓的支持都不是很好,最后还是只能选择Java中牛逼的itext库,这个库是开源免费,商业收费的,意思是你要使用开源版本则需要将你的源代码也开源,如果不开源,则需要购买商业版本,具体费用则需要跟对方联系。这是家外国企业,国内有代理商,很多大厂都是用的他们的解决方案,可谓是行业顶流解决方案了。
itext5的就不介绍了,官方已经全面切换到7了。
implementation ‘com.itextpdf:itext7-core:7.1.13’
首先需要设置相关的属性:
/** * 初始化pdf */ private void initPDF(String saveFilePath) { try { PdfWriter pdfWriter = new PdfWriter(new FileOutputStream(saveFilePath)); pdfDocument = new PdfDocument(pdfWriter); //创建字体,自带的TIMES_ROMAN pdfFont = PdfFontFactory.createFont(StandardFonts.TIMES_ROMAN); //设置页面大小这里设置A4纸大小 PageSize ps = PageSize.A4; //获取页面的宽度像素 pageWidth = ps.getWidth(); document = new Document(pdfDocument, ps, true); //设置字体 document.setFont(pdfFont); //设置字体大小(都要自己设置常量) document.setFontSize(mValueFontSize); //设置字体颜色 document.setFontColor(mColorBlack); // 分割线 lineSeparator = new LineSeparator(new DashedLine()); lineSeparator.setStrokeColor(DeviceRgb.BLUE); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
//基本的文本创建
Text shopName = new Text(getString(R.string.pdf_shop_name));
Text shopNameValue = new Text(workShopInfo.getShopName());
//创建一个段落
Paragraph shopNamePar = new Paragraph();
//将文本添加到段落中,可以添加多个文本,文本也可以设置不同的颜色字体,设置方式同初始化中的一样。
shopNamePar.add(shopName);
shopNamePar.add(shopNameValue);
//最后将段落添加到文档中就可以了。
document.add(shopNamePar);
首先要设置宽占比:
//设置表格宽占比
UnitValue[] resultArray = new UnitValue[3];
resultArray[0] = UnitValue.createPercentValue(20f);
resultArray[1] = UnitValue.createPercentValue(60f);
resultArray[2] = UnitValue.createPercentValue(20f);
然后创建Table:
//创建表格
Table table = new Table(resultArray).useAllAvailableWidth();
然后创建单元格:
Cell leftCell = new Cell();
之后可以将上面创建的段落添加到单元格中:
//注意必须是Paragraph,Text不能直接添加
leftcell.add(shopNamePar);
最后将cell添加到表格中就行了:
table.addCell(leftcell);
注意:单元格从左至右依次排列,所以想通过循环依次赋值的话,也要遵循这个原则准备数据源,不是以列为绘制方向的。
技巧:单元格内容默认是左对齐的如果需要居中对齐,则需要设置:
//水平居中
cell.setVerticalAlignment(VerticalAlignment.MIDDLE);
//添加文本
cell.add(new Paragraph("text"));
//添加文本后在设置文本对齐方式,这样才能居中对齐
cell.setTextAlignment(TextAlignment.CENTER);
table.addCell(cell);
掌握Text和table的用法,基本能够处理大部分的需求了。也能够绘制出整齐的文档了。
本文的文本类型不包括中文,中午需要对应能显示中文的字库,这里就没有延展了,本文的主旨是能解决大部分的问题,其他方面的问题需要自己去探索,自己去发现,才能掌握的更透彻。
此外我在开发过程中,发现,有些字符,字库中没有,如℃,没有的话,生成的文档会显示不出来。解决办法是替换掉对应的字符:
public static String replaceSpecialCharacters(String str){
return str.replace("℃","°C")
.replace("℉","°F");
}
另外在table中,如果遇到纯数字,没有分开的字符,这个框架不会自动换行,这是他们框架的一个缺失点。解决方案的话,需要自己根据表格宽度,计算到那个字符后面加个空格,系统会根据空格自动换行。解决方案如下:
/** * 处理表格中没有空格分开的文本会导致表格超宽不换行显示导致错乱的问题 * 第三方库存在连串数字不会触发换行的问题,只能手动加空格 * * @param text 表格中的文本 * @param table 表格类 * @param column 那一列 */ public String processTabularSuperWideText(String text, Table table, int column) { //文本宽度 double contentWidth = pdfFont.getContentWidth(new PdfString(text)) * pdfFont.getFontMatrix()[0] * mValueFontSize; //表格的总宽度 float tableWidth = pageWidth - document.getLeftMargin() - document.getRightMargin(); //当前对应显示的列的宽度 float columnWidth = tableWidth * (table.getColumnWidth(column).getValue() / 100f); //如果表格中的文本宽度计算值大于列的宽度,则需要做处理,反之不做处理 if (contentWidth > columnWidth) { //由于是根据空格来换行的,所以用空格切割字符串 String[] contentSplits = text.split(" "); //切割完的还要再拼接 StringBuffer contentBuff = new StringBuffer(); //遍历数组,对比每个切割后的字符串是否超过了列的宽度,如果超过了列的宽度,则需要添加空格 for (int i = 0; i < contentSplits.length; i++) { //这里必须用框架中计算内容宽度的方法才能准确计算出文本所占的宽度 double itemWidth = pdfFont.getContentWidth(new PdfString(contentSplits[i])) * pdfFont.getFontMatrix()[0] * mValueFontSize; //如果切割的单个字符串还大于列宽,则需要切割 if (itemWidth > columnWidth) { //超过列宽,则计算每个字符的宽度,然后累加字符宽度,直到达到列宽 StringBuffer stringBuff = new StringBuffer(); String itemStr = contentSplits[i]; char[] chars = itemStr.toCharArray(); //累加字符宽度 double addCharsWidth = 0; //保留一定的间隔,使其不充满整个列 double interval = 18; //遍历字符数组 for (int a = 0; a < chars.length; a++) { double charWidth = pdfFont.getContentWidth(new PdfString(String.valueOf(chars[a]))) * pdfFont.getFontMatrix()[0] * mValueFontSize; addCharsWidth = addCharsWidth + charWidth; //达到列宽则加空格,使其能自动换行 if (!(addCharsWidth < columnWidth - interval)) { stringBuff.append(" "); addCharsWidth = 0; } //合并字符为字符串 stringBuff.append(chars[a]); } stringBuff.append(" "); contentBuff.append(stringBuff); } else { contentBuff.append(contentSplits[i]).append(" "); } } return contentBuff.toString(); } else { return text; } }
如果此上方案解决了您的问题,请点赞加收藏关注一下,谢谢支持。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。