如果cellData 中有☑,则对将字符串进行拆分,分别显示
PdfProducer.java
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.export.pdf;
import com.bstek.ureport.build.paging.Page;
import com.bstek.ureport.chart.ChartData;
import com.bstek.ureport.definition.Alignment;
import com.bstek.ureport.definition.CellStyle;
import com.bstek.ureport.definition.Orientation;
import com.bstek.ureport.definition.Paper;
import com.bstek.ureport.exception.ReportComputeException;
import com.bstek.ureport.export.FullPageData;
import com.bstek.ureport.export.PageBuilder;
import com.bstek.ureport.export.Producer;
import com.bstek.ureport.model.Image;
import com.bstek.ureport.model.*;
import com.bstek.ureport.utils.ImageUtils;
import com.bstek.ureport.utils.UnitUtils;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2017年3月10日
*/
public class PdfProducer implements Producer {
private static BaseFont wingdings2Font;
static {
try {
wingdings2Font = BaseFont.createFont(
PdfProducer.class.getResource("/font/Wingdings2.ttf").getPath(),
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED
);
} catch (Exception e) {
throw new RuntimeException("Failed to load Wingdings2 font", e);
}
}
@Override
public void produce(Report report, OutputStream outputStream) {
Paper paper = report.getPaper();
int width = paper.getWidth();
int height = paper.getHeight();
Rectangle pageSize = new RectangleReadOnly(width, height);
if (paper.getOrientation().equals(Orientation.landscape)) {
pageSize = pageSize.rotate();
}
int leftMargin = paper.getLeftMargin();
int rightMargin = paper.getRightMargin();
int topMargin = paper.getTopMargin();
int bottomMargin = paper.getBottomMargin();
Document document = new Document(pageSize, leftMargin, rightMargin, topMargin, bottomMargin);
try {
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
PageHeaderFooterEvent headerFooterEvent = new PageHeaderFooterEvent(report);
writer.setPageEvent(headerFooterEvent);
document.open();
List<Column> columns = report.getColumns();
List<Integer> columnsWidthList = new ArrayList<Integer>();
int[] intArr = buildColumnSizeAndTotalWidth(columns, columnsWidthList);
int colSize = intArr[0], totalWidth = intArr[1];
int[] columnsWidth = new int[columnsWidthList.size()];
for (int i = 0; i < columnsWidthList.size(); i++) {
columnsWidth[i] = columnsWidthList.get(i);
}
FullPageData pageData = PageBuilder.buildFullPageData(report);
List<List<Page>> list = pageData.getPageList();
if (list.size() > 0) {
int columnCount = paper.getColumnCount();
int w = columnCount * totalWidth + (columnCount - 1) * paper.getColumnMargin();
int size = columnCount + (columnCount - 1);
int[] widths = new int[size];
for (int i = 0; i < size; i++) {
int mode = (i + 1) % 2;
if (mode == 0) {
widths[i] = paper.getColumnMargin();
} else {
widths[i] = totalWidth;
}
}
float tableHeight = pageSize.getHeight() - paper.getTopMargin() - paper.getBottomMargin();
Map<Row, Map<Column, Cell>> cellMap = report.getRowColCellMap();
for (List<Page> pages : list) {
PdfPTable table = new PdfPTable(size);
table.setLockedWidth(true);
table.setTotalWidth(w);
table.setWidths(widths);
table.setHorizontalAlignment(Element.ALIGN_LEFT);
int ps = pages.size();
for (int i = 0; i < ps; i++) {
if (i > 0) {
PdfPCell pdfMarginCell = new PdfPCell();
pdfMarginCell.setBorder(Rectangle.NO_BORDER);
table.addCell(pdfMarginCell);
}
Page page = pages.get(i);
PdfPTable childTable = new PdfPTable(colSize);
childTable.setLockedWidth(true);
childTable.setTotalWidth(totalWidth);
childTable.setWidths(columnsWidth);
childTable.setHorizontalAlignment(Element.ALIGN_LEFT);
List<Row> rows = page.getRows();
for (Row row : rows) {
Map<Column, Cell> colMap = cellMap.get(row);
if (colMap == null) {
continue;
}
for (Column col : columns) {
if (col.getWidth() < 1) {
continue;
}
Cell cell = colMap.get(col);
if (cell == null) {
continue;
}
int cellHeight = buildCellHeight(cell, rows);
PdfPCell pdfcell = buildPdfPCell(cell, cellHeight);
childTable.addCell(pdfcell);
}
}
float childTableHeight = childTable.calculateHeights();
if (tableHeight > childTableHeight) {
for (int j = 0; j < columns.size(); j++) {
PdfPCell lastCell = new PdfPCell();
lastCell.setBorder(Rectangle.NO_BORDER);
childTable.addCell(lastCell);
}
}
PdfPCell pdfContainerCell = new PdfPCell(childTable);
pdfContainerCell.setBorder(Rectangle.NO_BORDER);
table.addCell(pdfContainerCell);
}
if (ps < columnCount) {
int left = columnCount - ps;
for (int i = 0; i < left; i++) {
PdfPCell pdfMarginCell = new PdfPCell();
pdfMarginCell.setBorder(Rectangle.NO_BORDER);
table.addCell(pdfMarginCell);
pdfMarginCell = new PdfPCell();
pdfMarginCell.setBorder(Rectangle.NO_BORDER);
table.addCell(pdfMarginCell);
}
}
document.add(table);
document.newPage();
}
} else {
List<Page> pages = report.getPages();
Map<Row, Map<Column, Cell>> cellMap = report.getRowColCellMap();
for (Page page : pages) {
PdfPTable table = new PdfPTable(colSize);
table.setLockedWidth(true);
table.setTotalWidth(totalWidth);
table.setWidths(columnsWidth);
table.setHorizontalAlignment(Element.ALIGN_LEFT);
List<Row> rows = page.getRows();
for (Row row : rows) {
Map<Column, Cell> colMap = cellMap.get(row);
if (colMap == null) {
continue;
}
for (Column col : columns) {
if (col.getWidth() < 1) {
continue;
}
Cell cell = colMap.get(col);
if (cell == null) {
continue;
}
int cellHeight = buildCellHeight(cell, rows);
PdfPCell pdfcell = buildPdfPCell(cell, cellHeight);
table.addCell(pdfcell);
}
}
document.add(table);
document.newPage();
}
}
document.close();
} catch (Exception ex) {
throw new ReportComputeException(ex);
}
}
private int buildCellHeight(Cell cell, List<Row> rows) {
int height = cell.getRow().getRealHeight();
int rowSpan = cell.getPageRowSpan();
if (rowSpan > 0) {
int pos = rows.indexOf(cell.getRow());
int start = pos + 1, end = start + rowSpan - 1;
for (int i = start; i < end; i++) {
height += rows.get(i).getRealHeight();
}
}
return height;
}
private PdfPCell buildPdfPCell(Cell cellInfo, int cellHeight) throws Exception {
CellStyle style = cellInfo.getCellStyle();
CellStyle customStyle = cellInfo.getCustomCellStyle();
CellStyle rowStyle = cellInfo.getRow().getCustomCellStyle();
CellStyle colStyle = cellInfo.getColumn().getCustomCellStyle();
PdfPCell cell = newPdfCell(cellInfo, cellHeight);
cell.setPadding(0);
cell.setBorder(PdfPCell.NO_BORDER);
cell.setCellEvent(new CellBorderEvent(style, customStyle));
int rowSpan = cellInfo.getPageRowSpan();
if (rowSpan > 0) {
cell.setRowspan(rowSpan);
}
int colSpan = cellInfo.getColSpan();
if (colSpan > 0) {
cell.setColspan(colSpan);
}
Alignment align = style.getAlign();
if (customStyle != null && customStyle.getAlign() != null) {
align = customStyle.getAlign();
}
if (rowStyle != null && rowStyle.getAlign() != null) {
align = rowStyle.getAlign();
}
if (colStyle != null && colStyle.getAlign() != null) {
align = colStyle.getAlign();
}
if (align != null) {
if (align.equals(Alignment.left)) {
cell.setHorizontalAlignment(Element.ALIGN_LEFT);
} else if (align.equals(Alignment.center)) {
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
} else if (align.equals(Alignment.right)) {
cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
}
}
Alignment valign = style.getValign();
if (customStyle != null && customStyle.getValign() != null) {
valign = customStyle.getValign();
}
if (rowStyle != null && rowStyle.getValign() != null) {
valign = rowStyle.getValign();
}
if (colStyle != null && colStyle.getValign() != null) {
valign = colStyle.getValign();
}
if (valign != null) {
if (valign.equals(Alignment.top)) {
cell.setVerticalAlignment(Element.ALIGN_TOP);
} else if (valign.equals(Alignment.middle)) {
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
} else if (valign.equals(Alignment.bottom)) {
cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
}
}
String bgcolor = style.getBgcolor();
if (customStyle != null && StringUtils.isNotBlank(customStyle.getBgcolor())) {
bgcolor = customStyle.getBgcolor();
}
if (rowStyle != null && StringUtils.isNotBlank(rowStyle.getBgcolor())) {
bgcolor = rowStyle.getBgcolor();
}
if (colStyle != null && StringUtils.isNotBlank(colStyle.getBgcolor())) {
bgcolor = colStyle.getBgcolor();
}
if (StringUtils.isNotEmpty(bgcolor)) {
String[] colors = bgcolor.split(",");
cell.setBackgroundColor(new BaseColor(Integer.valueOf(colors[0]), Integer.valueOf(colors[1]), Integer.valueOf(colors[2])));
}
return cell;
}
private int[] buildColumnSizeAndTotalWidth(List<Column> columns, List<Integer> list) {
int count = 0, totalWidth = 0;
for (int i = 0; i < columns.size(); i++) {
Column col = columns.get(i);
int width = col.getWidth();
if (width < 1) {
continue;
}
count++;
list.add(width);
totalWidth += width;
}
return new int[]{count, totalWidth};
}
private PdfPCell newPdfCell(Cell cellInfo, int cellHeight) throws Exception {
PdfPCell cell = null;
Object cellData = cellInfo.getFormatData();
if (cellData instanceof Image) {
Image img = (Image) cellData;
cell = new PdfPCell(buildPdfImage(img.getBase64Data(), 0, 0));
} else if (cellData instanceof ChartData) {
ChartData chartData = (ChartData) cellData;
String base64Data = chartData.retriveBase64Data();
if (base64Data != null) {
Image img = new Image(base64Data, chartData.getWidth(), chartData.getHeight());
cell = new PdfPCell(buildPdfImage(img.getBase64Data(), 0, 0));
} else {
cell = new PdfPCell();
CellPhrase pargraph = new CellPhrase(cellInfo, "");
cell.setPhrase(pargraph);
cell.setFixedHeight(cellHeight);
}
} else {
cell = new PdfPCell();
if (cellData != null && cellData instanceof String && cellData.toString().indexOf("☑")>-1) {
Paragraph paragraph = new Paragraph();
List<String> cellDataList = splitStringWithSplitChar(cellData.toString(), "☑");
for (int i = 0; i < cellDataList.size(); i++) {
String cellDataStr = cellDataList.get(i);
if ("☑".equals(cellDataStr)) {
paragraph.add(new SymbolPhrase(cellInfo, cellDataStr));
} else {
paragraph.add(new CellPhrase(cellInfo,cellDataStr));
}
}
cell.setPhrase(paragraph);
}else{
CellPhrase pargraph = new CellPhrase(cellInfo, cellData);
cell.setPhrase(pargraph);
}
cell.setFixedHeight(cellHeight);
}
CellStyle style = cellInfo.getCellStyle();
if (style != null && style.getLineHeight() > 0) {
cell.setLeading(style.getLineHeight(), style.getLineHeight());
}
return cell;
}
public static List<String> splitStringWithSplitChar(String input,String splitChar) {
List<String> result = new ArrayList<>();
int startIndex = 0;
int index;
while ((index = input.indexOf(splitChar, startIndex)) != -1) {
if (index > startIndex) {
result.add(input.substring(startIndex, index));
}
result.add(splitChar);
startIndex = index + 1;
}
if (startIndex < input.length()) {
result.add(input.substring(startIndex));
}
return result;
}
private com.itextpdf.text.Image buildPdfImage(String base64Data, int width, int height) throws Exception {
com.itextpdf.text.Image pdfImg = null;
InputStream input = ImageUtils.base64DataToInputStream(base64Data);
try {
byte[] bytes = IOUtils.toByteArray(input);
pdfImg = com.itextpdf.text.Image.getInstance(bytes);
float imgWidth = pdfImg.getWidth();
float imgHeight = pdfImg.getHeight();
if (width == 0) {
width = Float.valueOf(imgWidth).intValue();
}
if (height == 0) {
height = Float.valueOf(imgHeight).intValue();
}
width = UnitUtils.pixelToPoint(width - 2);
height = UnitUtils.pixelToPoint(height - 2);
pdfImg.scaleToFit(width, height);
} finally {
IOUtils.closeQuietly(input);
}
return pdfImg;
}
}
SymbolPhrase 用来实现通过加载自定义字体,来显示方框对号
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.ureport.export.pdf;
import com.bstek.ureport.model.Cell;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
/**
* 专门用来处理特殊符号
* @author Jacky.gao
* @since 2014年4月17日
*/
public class SymbolPhrase extends Phrase {
private static BaseFont wingdings2Font;
static {
try {
wingdings2Font = BaseFont.createFont(
PdfProducer.class.getResource("/font/Wingdings2.ttf").getPath(),
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED
);
} catch (Exception e) {
throw new RuntimeException("Failed to load Wingdings2 font", e);
}
}
public SymbolPhrase(Cell cell, Object cellData) {
Font font = new Font(wingdings2Font,12);
setFont(font);
add("R");
}
}
将 Wingdings 2.TTF 放到classpath下的font目录即可。