iText实践1:基于PdfPTable的藏,汉文字混显报表

引言

iReport能处理绝大部分的报表,也包括图表报表,也能用躲着TTF字体设置显示文字,但只能处理汉字,涉及到藏文,彝文或者其他民族文字时,iReport也显得很无助,好不容易找到一种方法,即通过标注为html标签,这种方法在iReport自带的JRViewer预览是可以的,但是转换为jrxml或者jasper,与Java结合时,iReport又哇哇大哭,直报异常。

好在,iReport的底层也是调用的iText,iText在处理文字的基本单元为Chunk,可以设置为单独的字符,并可以为该字符设置相应的字体,于是,便直接面向iText编程,用他来处理并显示藏文,汉文混显报表。

通过iText提供的PdfPTable来轻松布局,如下为iText的报表部分效果(只有部分内容才涉及到多文字混合显示,处理与实现见后面)

iText实践1:基于PdfPTable的藏,汉文字混显报表_第1张图片


此处的显示效果为汉文和英文都是应用的楷体文字,藏文应用的是喜马拉雅字体。

具体实现

iText提供的PdfPTable是通过AddCell的方式实现自动行计算,可设置列数与每个列宽度的比例,可实现Row Span, Col Span,跨行,跨列,可以为单元格设置样式,如边框,对齐方式,旋转等,提供的代码中都有样例。

1.可在项目目录下指定文件夹和文件名

public static final String BASE_DIR = "PDF/";
	public static final String RESULT = BASE_DIR + "report.pdf";
	static {
		File f = new File(BASE_DIR);
		if (!f.exists()) {
			f.mkdir();
		}
	}
2.创建PDF文档实例,并接收一个返回的表格对象

这里设置了文档的宽高,边框margin

public void build() throws Exception {
		Rectangle pagesize = new Rectangle(650f, 720f);
		Document document = new Document(pagesize, 5f,5f, 36f, 36f);
		//Document document = new Document();
		PdfWriter.getInstance(document, new FileOutputStream(RESULT));
		document.open();
		//document.setPageSize(PageSize.A5);
        //document.setMargins(36, 36, 72, 72);
        document.setMarginMirroring(true);
		document.add(createPdfTable());
		document.close();
	}
	
3.开始创建表格

设置样式的的方法,这里没有完整封装,没有合适规范,只做参考。

private static void setCellStyle(PdfPCell cell) {
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setNoWrap(false);
		cell.setPadding(10);
	}
	
	private static void setCellStyle2(PdfPCell cell) {
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		cell.setNoWrap(false);
		cell.setPadding(5);
	}
	
	private static void setCellStyle3(PdfPCell cell) {
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setNoWrap(false);
	}
	
	private static void setCellStyle4(PdfPCell cell) {
		cell.setHorizontalAlignment(Element.ALIGN_LEFT);
		cell.setPaddingLeft(20);
		cell.setPaddingBottom(10);
		cell.setPaddingRight(20);
		cell.setNoWrap(false);
	}
在处理文字混显的时候,需要判断是否为汉文或者藏文,用到一个辅助方法,由于藏文字符,我们统一采用微软提供的喜马拉雅字体来显示,所以需要应用该字体,并应用为UTF-8编码。在UTF-8编码文字中,藏文区间为【 0x0F00--0x0FFF】,所以这里只须判断是否文藏文。由于汉字种类繁多,标点符号等还囊括了英文的编码范围,所以通过以下方法可直接做常规区分

public static final int getLang(char ch) {
		if ((ch >= 0x0F00) && (ch <= 0x0FFF) ? true : false) {
			return 1; //藏文
		} 
		return 0; //中文或英文获其他
	}
在代码实现中,把一段多文字的String(可以通过数据库查询,也可配置为文本文件),解析为多个块文本,同种文字的字符封装在一个Span中,最后存放于List中,用到了一个Span显示类

class Span {
	int lang;
	String chs;
	
	/**
	 * @param lang
	 * @param chs
	 */
	public Span(int lang, String chs) {
		super();
		this.lang = lang;
		this.chs = chs;
	}
	public int getLang() {
		return lang;
	}
	public void setLang(int lang) {
		this.lang = lang;
	}
	public String getChs() {
		return chs;
	}
	public void setChs(String chs) {
		this.chs = chs;
	}
	
	@Override
	public String toString() {
		return "Span [lang=" + lang + ", chs=" + chs + "]";
	}
	
}
最终算法为(此处算法可优化,希望能有人指点)

@Test
	public void ch() throws Exception {
		String str = "你好,这里是一段中文,这里是一段藏文。ལལསདབགསདབགས这里是一段英文དབ་འསདལབགཇ";

		StringBuffer sb = new StringBuffer();
		List<Span> list = new ArrayList<Span>();
		int lang = 0; //默认是汉
		for (int i = 0; i < str.length(); i++) {
			char ch = str.charAt(i);
			int res = CharacterHelper.getLang(ch);
			System.out.print(ch+"-" + res+"|");
			if (res != lang) { 
				list.add(new Span(lang, sb.toString()));
				lang = res;
				sb.setLength(0);
			}
			if (res == 0) {
				sb.append(ch);
				lang = 0;
			} else if (res == 1) {
				sb.append(ch);
				lang = 1;
			}
		}
		if (sb.length()>0) {
			
			list.add(new Span(lang, sb.toString()));
		}
		System.out.println();
		for (Span s : list) {
			System.out.println(s);
		}
	}

最后创建报表的方法如下

	/**
	 * @return
	 * @throws DocumentException
	 */
	public static PdfPTable createPdfTable() throws DocumentException {
		PdfPTable table = new PdfPTable(8);
		table.setWidths(new float[]{0.6f, 0.8f,1,1,1,1,1, 1});
		Font titleFont = new Font(HelloWorldPdf.STKAIti);
		titleFont.setSize(26);
		PdfPCell cell  = new PdfPCell(new Phrase(new Chunk("四川民族出版社书稿审读意见", titleFont)));
		cell.setColspan(8);
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		cell.setNoWrap(false);
		cell.setPadding(10);
		table.addCell(cell);
		
		//第二行
		Font font = new Font(HelloWorldPdf.STKAIti);
		PdfPCell cell2 = new PdfPCell(new Phrase(new Chunk("书稿名", font)));
		setCellStyle(cell2);
		cell2.setColspan(2);
		table.addCell(cell2);
		
		cell2 = new PdfPCell(new Phrase(new Chunk("曲拉--藏地女性长篇小说第一部", font)));
		setCellStyle(cell2);
		cell2.setColspan(6);
		table.addCell(cell2); //${书稿名}
		
		//第三行
		PdfPCell cell3 = new PdfPCell(new Phrase(new Chunk("类别", font)));
		setCellStyle(cell3);
		cell3.setColspan(2);
		table.addCell(cell3);
		
		cell3 = new PdfPCell(new Phrase(new Chunk("17.少数民族文字", font)));
		setCellStyle(cell3);
		cell3.setColspan(4);
		table.addCell(cell3);
		
		cell3 = new PdfPCell(new Phrase(new Chunk("千字数", font)));
		setCellStyle(cell3);
		table.addCell(cell3);
		
		cell3 = new PdfPCell(new Phrase(new Chunk("210", font)));
		setCellStyle(cell3);
		table.addCell(cell3);
		
		//第四行
		PdfPCell cell4 = new PdfPCell(new Phrase(new Chunk("责编", font)));
		setCellStyle(cell4);
		cell4.setColspan(2);
		table.addCell(cell4);
		
		cell4 = new PdfPCell(new Phrase(new Chunk("林么周 才秀加", font)));
		setCellStyle(cell4);
		cell4.setColspan(3);
		table.addCell(cell4);
		
		cell4 = new PdfPCell(new Phrase(new Chunk("组稿者", font)));
		setCellStyle(cell4);
		table.addCell(cell4);
		
		cell4 = new PdfPCell(new Phrase(new Chunk("", font)));
		setCellStyle(cell4);
		cell4.setColspan(2);
		table.addCell(cell4);
		
		//第五行
		Font mdFont = new Font(HelloWorldPdf.STKAIti);
		mdFont.setSize(20);
		PdfPCell cell5 = new PdfPCell(new Phrase(new Chunk("作\n者\n简\n介", mdFont)));
		cell5.setRowspan(3);
		setCellStyle(cell5);
		table.addCell(cell5);
		
		cell5 =  new PdfPCell(new Phrase(new Chunk("姓名", font)));
		setCellStyle(cell5);
		table.addCell(cell5);
		cell5 =  new PdfPCell(new Phrase(new Chunk("毛卡加", font)));
		setCellStyle(cell5);
		cell5.setColspan(2);
		table.addCell(cell5);
		cell5 =  new PdfPCell(new Phrase(new Chunk("性别", font)));
		setCellStyle(cell5);
		table.addCell(cell5);
		cell5 =  new PdfPCell(new Phrase(new Chunk("女", font)));
		setCellStyle(cell5);
		table.addCell(cell5);
		cell5 =  new PdfPCell(new Phrase(new Chunk("年龄", font)));
		setCellStyle(cell5);
		table.addCell(cell5);
		cell5 =  new PdfPCell(new Phrase(new Chunk("", font)));
		setCellStyle(cell5);
		table.addCell(cell5);
		
		//第六行
		cell5 =  new PdfPCell(new Phrase(new Chunk("职称", font)));
		setCellStyle(cell5);
		table.addCell(cell5);	
		cell5 =  new PdfPCell(new Phrase(new Chunk("", font)));
		setCellStyle(cell5);
		cell5.setColspan(2);
		table.addCell(cell5);
		cell5 =  new PdfPCell(new Phrase(new Chunk("单位", font)));
		setCellStyle(cell5);
		table.addCell(cell5);
		cell5 =  new PdfPCell(new Phrase(new Chunk("", font)));
		setCellStyle(cell5);
		cell5.setColspan(3);
		table.addCell(cell5);
		//第七行
		cell5 =  new PdfPCell(new Phrase(new Chunk("主要\n研究\n方向\n、\n成果", font)));
		setCellStyle(cell5);
		table.addCell(cell5);
		cell5 =  new PdfPCell(new Phrase(new Chunk("卡毛加、女,青海省教育厅民族教材编译中心 副译审。主要学术成果有: 《妇女在藏族教育中的作"+
				"用》和《浅谈发展藏语文的几点看法》在全省藏文教育教学论文评评选中荣获一等奖和二等奖。", font)));
		setCellStyle2(cell5);
		cell5.setColspan(6);
		table.addCell(cell5);
		
		//三审内容
		Font xmFont = new Font(HelloWorldPdf.STKAIti);
		mdFont.setSize(16);
		PdfPCell cell6 = new PdfPCell(new Phrase(new Chunk("初审意见", mdFont)));
		cell6.setColspan(8);
		cell6.setPaddingBottom(10);
		setCellStyle3(cell6);
		cell6.setBorderWidthLeft(1);
		cell6.setBorderWidthRight(1);
		cell6.setBorderWidthBottom(0f);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("书稿的内容、特点及价值:", font)));
		cell6.setColspan(8);
		setCellStyle2(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk( ConfigUtil.getVal("report/content.properties").toString(), xmFont)));
		cell6.setColspan(8);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("书稿存在的问题(标出问题所在的页面) :", font)));
		cell6.setColspan(8);
		setCellStyle2(cell6);
		table.addCell(cell6);
		
		
		/**算法一:直接处理文本**/
		String content = ConfigUtil.getVal("report/content2.properties")
				.toString();
		Paragraph pc = new Paragraph();
		StringBuffer sb = new StringBuffer();
		List<Span> list = new ArrayList<Span>();
		int lang = 0; //默认是汉
		for (int i = 0; i < content.length(); i++) {
			char ch = content.charAt(i);
			int res = CharacterHelper.getLang(ch);
			System.out.print(ch+"-" + res+"|");
			if (res != lang) { 
				list.add(new Span(lang, sb.toString()));
				lang = res;
				sb.setLength(0);
			}
			if (res == 0) {
				sb.append(ch);
				lang = 0;
			} else if (res == 1) {
				sb.append(ch);
				lang = 1;
			}
		}
		if (sb.length()>0) {
			
			list.add(new Span(lang, sb.toString()));
		}
		
		System.out.println();
		Chunk cc = null;
		for (Span s : list) {
			if (s.getLang() == 0) {
				 cc = new Chunk(s.getChs(), HelloWorldPdf.STKAIti);
			} else if (s.getLang() == 1) {
				cc = new Chunk(s.getChs(), HelloWorldPdf.HIMALAYA);
			}
			pc.add(cc);
		}
		
		cell6 = new PdfPCell(pc);
		cell6.setColspan(8);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		
		cell6 = new PdfPCell(new Phrase(new Chunk("提请复审解决的问题:", font)));
		cell6.setColspan(8);
		setCellStyle2(cell6);
		table.addCell(cell6);
		cell6 = new PdfPCell(new Phrase(new Chunk("\n\n\n\n", xmFont)));
		cell6.setColspan(8);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("对复终审意见的处理:", font)));
		cell6.setColspan(8);
		setCellStyle2(cell6);
		table.addCell(cell6);
		cell6 = new PdfPCell(new Phrase(new Chunk("\n\n\n\n", xmFont)));
		cell6.setColspan(8);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("初审时间:▁▁▁▁年▁▁▁▁月 ▁▁▁▁日", font)));
		cell6.setColspan(6);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("签名:▁▁▁▁▁", font)));
		cell6.setColspan(2);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
	    cell6 = new PdfPCell(new Phrase(new Chunk("复审意见", mdFont)));
		cell6.setColspan(8);
		cell6.setPaddingBottom(10);
		setCellStyle3(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("对书稿及对初审意见的评价:", font)));
		cell6.setColspan(8);
		setCellStyle2(cell6);
		table.addCell(cell6);
		cell6 = new PdfPCell(new Phrase(new Chunk( ConfigUtil.getVal("report/content.properties").toString(), xmFont)));
		cell6.setColspan(8);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("对初审提出问题的处理:", font)));
		cell6.setColspan(8);
		setCellStyle2(cell6);
		table.addCell(cell6);
		cell6 = new PdfPCell(new Phrase(new Chunk("\n\n\n\n", xmFont)));
		cell6.setColspan(8);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("提请终审解决的问题及对书稿的处理意见:", font)));
		cell6.setColspan(8);
		setCellStyle2(cell6);
		table.addCell(cell6);
		cell6 = new PdfPCell(new Phrase(new Chunk("\n\n\n\n", xmFont)));
		cell6.setColspan(8);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("复审时间:▁▁▁▁年▁▁▁▁月 ▁▁▁▁日", font)));
		cell6.setColspan(6);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("签名:▁▁▁▁▁", font)));
		cell6.setColspan(2);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("终审意见", mdFont)));
		cell6.setColspan(8);
		cell6.setPaddingBottom(10);
		setCellStyle3(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("对书稿及初、复审意见的评价:", font)));
		cell6.setColspan(8);
		setCellStyle2(cell6);
		table.addCell(cell6);
		cell6 = new PdfPCell(new Phrase(new Chunk( ConfigUtil.getVal("report/content.properties").toString(), xmFont)));
		cell6.setColspan(8);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("处理意见:", font)));
		cell6.setColspan(8);
		setCellStyle2(cell6);
		table.addCell(cell6);
		cell6 = new PdfPCell(new Phrase(new Chunk("\n\n\n\n", xmFont)));
		cell6.setColspan(8);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("终审时间:▁▁▁▁年▁▁▁▁月 ▁▁▁▁日", font)));
		cell6.setColspan(6);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		cell6 = new PdfPCell(new Phrase(new Chunk("签名:▁▁▁▁▁", font)));
		cell6.setColspan(2);
		setCellStyle4(cell6);
		table.addCell(cell6);
		
		table.completeRow();
		table.setHorizontalAlignment(Element.ALIGN_CENTER);
		table.setSpacingBefore(10);
		
		return table;
	}

ConfigUtil为读取配置文件内容的工具,不足为意。

---  2014-10-13      及于此


你可能感兴趣的:(pdf,报表,IREPORT,itext)