package com.wdw.web.manage.wgsx;
import com.itextpdf.text.*;
import com.itextpdf.text.log.Level;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.codec.Base64;
import com.itextpdf.tool.xml.*;
import com.itextpdf.tool.xml.css.CssFilesImpl;
import com.itextpdf.tool.xml.css.CssUtils;
import com.itextpdf.tool.xml.css.StyleAttrCSSResolver;
import com.itextpdf.tool.xml.exceptions.LocaleMessages;
import com.itextpdf.tool.xml.exceptions.RuntimeWorkerException;
import com.itextpdf.tool.xml.html.CssAppliersImpl;
import com.itextpdf.tool.xml.html.HTML;
import com.itextpdf.tool.xml.html.TagProcessorFactory;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import sun.misc.BASE64Encoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @author xupf@wangreat.com
* @create 2019-11-28 13:04
*/
public class TestChart {
public static void main(String[] args) {
StandardChartTheme mChartTheme = new StandardChartTheme("CN");
mChartTheme.setLargeFont(new Font("黑体", Font.BOLD, 20));
mChartTheme.setExtraLargeFont(new Font("宋体", Font.PLAIN, 15));
mChartTheme.setRegularFont(new Font("宋体", Font.PLAIN, 15));
ChartFactory.setChartTheme(mChartTheme);
CategoryDataset mDataset = getDataset();
JFreeChart mChart = ChartFactory.createLineChart(
"折线图",//图名字
"年份",//横坐标
"数量",//纵坐标
mDataset,//数据集
PlotOrientation.VERTICAL,
true, // 显示图例
true, // 采用标准生成器
false);// 是否生成超链接
// XYPlot xyplot = (XYPlot) mChart.getPlot();
// DateAxis domainAxis = (DateAxis) xyplot.getDomainAxis(); //x轴设置
// domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.MONTH, 3, new SimpleDateFormat("yyyy/MM/dd")));
CategoryPlot mPlot = (CategoryPlot)mChart.getPlot();
mPlot.setBackgroundPaint(Color.LIGHT_GRAY);
mPlot.setRangeGridlinePaint(Color.BLUE);//背景底部横虚线
mPlot.setOutlinePaint(Color.RED);//边界线
CategoryAxis domainAxis = mPlot.getDomainAxis();
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);
BufferedImage bufferedImage = mChart.createBufferedImage(1000, 500);
ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
try {
ImageIO.write(bufferedImage, "png", baos);//写入流中
byte[] bytes = baos.toByteArray();//转换成字节
BASE64Encoder encoder = new BASE64Encoder();
String png_base64 = encoder.encodeBuffer(bytes).trim();//转换成base64串
png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
System.out.println("data:image/png;base64," + png_base64);
png_base64 = "data:image/png;base64," + png_base64;
StringBuilder sb = new StringBuilder();
sb.append("<!DOCTYPE html\n" +
" PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
sb.append("<html>");
sb.append("<head>");
sb.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><style>body{font-family: SimSun;}</style>");
sb.append("</head>");
sb.append("<body>");
sb.append("<div>this is a first img</div>");
sb.append("<div>这是我的第一幅图片</div>");
sb.append("<img src=\""+png_base64+"\" width=\"500%\" height=\"500%\" />");
sb.append("</body>");
sb.append("</html>");
System.out.println(sb.toString());
String html = sb.toString();
String fileName = "test" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + ".pdf";
String pdfPath = "D:\\certs\\" + fileName;
// step 1 获取Document对象
Document document = new Document(PageSize.A4); // 设置打印为横向打印
// step 2 获取Pdf写实例
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(pdfPath));
// step 3 打开Document
document.open();
TagProcessorFactory tagProcessorFactory = Tags.getHtmlTagProcessorFactory();
tagProcessorFactory.removeProcessor(HTML.Tag.IMG);
tagProcessorFactory.addProcessor(new ImageTagProcessor(), HTML.Tag.IMG);
CssFilesImpl cssFiles = new CssFilesImpl();
cssFiles.add(XMLWorkerHelper.getInstance().getDefaultCSS());
StyleAttrCSSResolver cssResolver = new StyleAttrCSSResolver(cssFiles);
HtmlPipelineContext hpc = new HtmlPipelineContext(new CssAppliersImpl(new XMLWorkerFontProvider()));
hpc.setAcceptUnknown(true).autoBookmark(true).setTagFactory(tagProcessorFactory);
HtmlPipeline htmlPipeline = new HtmlPipeline(hpc, new PdfWriterPipeline(document, pdfWriter));
Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
XMLWorker worker = new XMLWorker(pipeline, true);
Charset charset = Charset.forName("UTF-8");
XMLParser xmlParser = new XMLParser(worker, charset);
xmlParser.parse(new ByteArrayInputStream(html.getBytes("UTF-8")), charset);
xmlParser.flush();
// step 4 Html文档字符串转Pdf
// XMLWorkerHelper.getInstance().parseXHtml(pdfWriter, document,
// new ByteArrayInputStream(html.getBytes("UTF-8")), Charset.forName("UTF-8"));
// step 5 关闭Document对象
document.close();
} catch (IOException | DocumentException e) {
e.printStackTrace();
}
// ChartFrame mChartFrame = new ChartFrame("折线图", mChart);
// mChartFrame.pack();
// mChartFrame.setVisible(true);
}
public static CategoryDataset getDataset() {
DefaultCategoryDataset mDataset = new DefaultCategoryDataset();
mDataset.addValue(1, "First", "2013/10/1");
mDataset.addValue(3, "First", "2014/5/1");
mDataset.addValue(2, "First", "2015/6/1");
mDataset.addValue(6, "First", "2016/7/1");
mDataset.addValue(5, "First", "2017/8/1");
mDataset.addValue(12, "First", "2018/9/1");
mDataset.addValue(13, "First", "2018/10/1");
mDataset.addValue(14, "First", "2018/11/1");
mDataset.addValue(15, "First", "2018/12/1");
mDataset.addValue(16, "First", "2018/7/1");
mDataset.addValue(14, "Second", "2013/10/1");
mDataset.addValue(13, "Second", "2014/5/1");
mDataset.addValue(12, "Second", "2015/6/1");
mDataset.addValue(9, "Second", "2016/7/1");
mDataset.addValue(5, "Second", "2017/8/1");
mDataset.addValue(7, "Second", "2018/9/1");
mDataset.addValue(8, "Second", "2018/10/1");
mDataset.addValue(9, "Second", "2018/11/1");
mDataset.addValue(10, "Second", "2018/12/1");
mDataset.addValue(11, "Second", "2018/7/1");
return mDataset;
}
}
class ImageTagProcessor extends com.itextpdf.tool.xml.html.Image {
private final CssUtils utils = CssUtils.getInstance();
private final Logger logger = LoggerFactory.getLogger(getClass());
/*
* (non-Javadoc)
*
* @see com.itextpdf.tool.xml.TagProcessor#endElement(com.itextpdf.tool.xml.Tag, java.util.List, com.itextpdf.text.Document)
*/
@Override
public List<Element> end(final WorkerContext ctx, final Tag tag, final List<Element> currentContent) {
final Map<String, String> attributes = tag.getAttributes();
String src = attributes.get(HTML.Attribute.SRC);
List<Element> elements = new ArrayList<Element>(1);
if (null != src && src.length() > 0) {
com.itextpdf.text.Image img = null;
if (src.startsWith("data:image/")) {
final String base64Data = src.substring(src.indexOf(",") + 1);
System.out.println("base64Data:" + base64Data);
try {
img = com.itextpdf.text.Image.getInstance(Base64.decode(base64Data));
} catch (Exception e) {
if (logger.isLogging(Level.ERROR)) {
logger.error(String.format(LocaleMessages.getInstance().getMessage(LocaleMessages.HTML_IMG_RETRIEVE_FAIL), src), e);
}
}
if (img != null) {
try {
String width = attributes.get(HTML.Attribute.WIDTH);
float widthInPoints = utils.parsePxInCmMmPcToPt(width);
String height = attributes.get(HTML.Attribute.HEIGHT);
if (width == null || height == null)
img.setScaleToFitLineWhenOverflow(true);
else
img.setScaleToFitLineWhenOverflow(false);
float heightInPoints = utils.parsePxInCmMmPcToPt(height);
if (widthInPoints > 0 && heightInPoints > 0) {
img.scaleAbsolute(widthInPoints, heightInPoints);
} else if (widthInPoints > 0) {
heightInPoints = img.getHeight() * widthInPoints
/ img.getWidth();
img.scaleAbsolute(widthInPoints, heightInPoints);
} else if (heightInPoints > 0) {
widthInPoints = img.getWidth() * heightInPoints
/ img.getHeight();
img.scaleAbsolute(widthInPoints, heightInPoints);
}
System.out.println("img:" + img);
final HtmlPipelineContext htmlPipelineContext = getHtmlPipelineContext(ctx);
elements.add(getCssAppliers().apply(new Chunk((com.itextpdf.text.Image) getCssAppliers().apply(img, tag, htmlPipelineContext), 0, 0, true), tag,
htmlPipelineContext));
} catch (NoCustomContextException e) {
throw new RuntimeWorkerException(e);
}
}
}
if (img == null) {
elements = super.end(ctx, tag, currentContent);
}
}
return elements;
}
}
中文显示问题
// 设置使用项目本省自带的字体,防止服务器上没有中文字体带来的问题
String vPath = ChartUtils.class.getClassLoader().getResource("").getPath();
logger.debug("vpath:" + vPath);
vPath = vPath + File.separator + "simsun.ttf";
logger.debug("vpath:" + vPath);
Font font = null;
try {
File file = new File(vPath);
FileInputStream fis = new FileInputStream(file);
font = Font.createFont(Font.TRUETYPE_FONT, fis);
fis.close();
font = font.deriveFont(Font.PLAIN, 18);
} catch (FontFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
StandardChartTheme mChartTheme = new StandardChartTheme("CN");
mChartTheme.setLargeFont(font);
mChartTheme.setExtraLargeFont(font);
mChartTheme.setRegularFont(font);
ChartFactory.setChartTheme(mChartTheme);
CategoryDataset mDataset = getChartsData(reportLists);
JFreeChart mChart = ChartFactory.createLineChart(
"",//图名字
"",//横坐标
"",//纵坐标
mDataset,//数据集
PlotOrientation.VERTICAL,
true, // 显示图例
true, // 采用标准生成器
false);// 是否生成超链接
mChart.getLegend().setItemFont(font);
CategoryPlot mPlot = (CategoryPlot)mChart.getPlot();
mPlot.setBackgroundPaint(Color.LIGHT_GRAY);
mPlot.setRangeGridlinePaint(Color.BLUE);//背景底部横虚线
mPlot.setOutlinePaint(Color.RED);//边界线
mPlot.getRenderer().setSeriesStroke(0, new BasicStroke(2F));
mPlot.getRenderer().setSeriesStroke(1, new BasicStroke(4F));
CategoryAxis domainAxis = mPlot.getDomainAxis();
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);
domainAxis.setLabelFont(font);
domainAxis.setTickLabelFont(font);
BufferedImage bufferedImage = mChart.createBufferedImage(1000, 500);
ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
try {
ImageIO.write(bufferedImage, "png", baos);//写入流中
byte[] bytes = baos.toByteArray();//转换成字节
BASE64Encoder encoder = new BASE64Encoder();
String png_base64 = encoder.encodeBuffer(bytes).trim();//转换成base64串
png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
logger.debug("data:image/jpg;base64," + png_base64);
png_base64 = "data:image/jpg;base64," + png_base64;
return png_base64;
} catch (IOException e) {
e.printStackTrace();
}