java html转pdf 换行使用插入字符

package com.hopechart.common.util;


import java.awt.Color;
import java.awt.Font;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;


import javax.servlet.http.HttpServletResponse;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;










import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;


import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;


public class GeneratePDFUtil {
private static final String font = "ex/font/simsun.ttc"; // 字体样式存放路径


private static Configuration $cfg = null; // 用于模版实例的创建以及缓存


private static String realpath = ""; // 当前项目所在目录


private static String encode = "gbk"; // 编码


/**
* 同步导出PDF
* @param response
* @param data pdf模板中需要的数据集合
* @param path 导出pdf内容中图表图片的相对路径
* @param pdfFileName 生成pdf文件名称
* @param pdfTemplate EL表达式转换模板文件
* @param dataTemplate PDF转换模板文件
*/
public synchronized static void syncReportPDF(HttpServletResponse response,
Map<String, Object> data, String path,String pdfFileName,String pdfTemplate,String dataTemplate) {
//导出pdf内容中图表图片的相对路径
realpath = path;
// 最终输出文件
String pdfFile = pdfFileName + ".pdf";
// 动态获取linux和windows下的分隔符
String separator = System.getProperty("file.separator");
// 图片文件目录
String imagePath = "file:///" + realpath + "images" + separator + "menu";

String template = pdfTemplate;//"WEB-INF/tpl/test_pdf_template.html";
// PDF转换模板文件
String template2 = dataTemplate;//"WEB-INF/tpl/test_data_template.html";
/*// EL表达式转换模板文件
String template = "WEB-INF/tpl/pdf_template.html";
// PDF转换模板文件
String template2 = "WEB-INF/tpl/data_template.html";
*/
// 格式化HTML
formatHtml(data, template, template2);
// 生成PDF
createPDF(template2, pdfFile, imagePath);
// 导出PDF
reportFile(response, pdfFile, "application/pdf");
}


/**
* 格式化HTML页面

* @param data
*            pdf文件的转速数据
* @param template
*            写好的模板文件
* @param template2
*            需要渲染模板文件
*/
private static void formatHtml(Map<String, Object> data, String template,
String template2) {
//初始化FreeMarker配置,创建一个Configuration实例
$cfg = new Configuration();
// FileWriter writer = null;
Writer out = null;
try {
//设置FreeMarker的模版文件位置 
$cfg.setDirectoryForTemplateLoading(new File(realpath));
//设置解码方式
$cfg.setDefaultEncoding(encode);
//使用Configuration实例来加载指定模板
Template tpl = $cfg.getTemplate(template);
//设置模板编码
tpl.setEncoding(encode);
File file = new File(realpath + template2);
//新建输出,生成html文件
out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(file), encode));
//将数据模型中的值合并到模板文件中,并将结果输出到out中
tpl.process(data, out);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


/**
* 生成pdf文件

* @param template2
*            导出模板文件
* @param pdfFile
*            pdf名称
* @param imagePath
*            pdf中图片的相对路径
*/
private static void createPDF(String template2, String pdfFile,
String imagePath) {
StringBuffer html = new StringBuffer();
BufferedReader reader = null;
OutputStream os = null;
try {
//读取模板文件,并设置指定的编码
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(realpath + template2), encode));
String row = null;
while ((row = reader.readLine()) != null) {//读取模板每一行
html.append(row);
}
os = new FileOutputStream(realpath+pdfFile);
//利用renderer来准备数据
ITextRenderer renderer = new ITextRenderer();
ITextFontResolver fontResolver = renderer.getFontResolver();
//设置创建PDF的时候要用的字体,此字体必须要和pdf模板的字体保持一致
fontResolver.addFont(realpath + font, BaseFont.IDENTITY_H,
BaseFont.NOT_EMBEDDED);
renderer.setDocumentFromString(html.toString());
// 解决图片的相对路径问题
renderer.getSharedContext().setBaseURL(imagePath);

renderer.layout();
renderer.createPDF(os);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


/**
* 导出pdf文件
* @param response
* @param filename
* @param type
*/
public static void reportFile(HttpServletResponse response,
String filename, String type) {
// 创建file对象
File file = new File(realpath+filename);
// 设置response的编码方式
response.setContentType(type);
// 写明要下载的文件的大小
response.setContentLength((int) file.length());
OutputStream out = null;
InputStream in = null;
try {
// 设置附加文件名
filename = new String(filename.getBytes("GB2312"), "ISO_8859_1");
response.setHeader("Content-Disposition", "attachment;filename="
+ filename);
// 从response对象中得到输出流,准备下载
out = response.getOutputStream();
out = new BufferedOutputStream(out);
in = new FileInputStream(file);
int b = 0;
byte[] buf = new byte[1024];
while ((b = in.read(buf, 0, buf.length)) != -1) {
out.write(buf, 0, b);
}
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


/**
* 使用JFreeChart生成报表

* @param data 获取data指定类型的数据
* @param tempPath 图片存放路径
* @param tempPath 图片名称
*/
public static void createChart(Map<String, Object> data, String tempPath,
String fileName) {
//生成的数据图表存放的路径
realpath = tempPath;
String path = realpath + "images/pdf/";
//转速分布数据
float[] carRevRate = (float[]) data.get("carRevRate");
// 生成发动机转速分布图
String[] carx = { "≤700", "≤800", "≤900", "≤1000", "≤1100", "≤1200",
"≤1300", "≤1400", "≤1500", "≤1600", "≤1800", "≤2000", "≤2200",
"≤2400", ">2400" };
if (fileName != null) {//如果指定保存图片的名称则使用指定名称,用于页面显示
saveAsFile(path + fileName, carx, carRevRate, new String[] {
"发动机转速分布图", "发动机转速(r/min)", "百分比(%)" }, 11);
} else {//否则使用默认图片名称,用于导出pdf文件
saveAsFile(path + "chartBar.png", carx, carRevRate, new String[] {
"发动机转速分布图", "发动机转速(r/min)", "百分比(%)" }, 11);
}
}


/**
* 生成JFreeChart,并保存为png图片

* @param outputPath 图片保存路径
* @param xText x轴上的刻度 
* @param xValue 数据
* @param params 数组[图表名称,横轴单位,纵轴单位]
* @param fontSize 字体大小
*/
public static void saveAsFile(String outputPath, String[] xText,
float[] xValue, String[] params, int fontSize) {
//创建CategoryDataset对象
CategoryDataset dataset = createDataset(xText, xValue);
//根据CategoryDataset生成JFreeChart对象
JFreeChart chart = createJFreeChart(dataset, params[0], params[1],
params[2], fontSize);
FileOutputStream out = null;
try {
out = new FileOutputStream(outputPath);
//保存为PNG文件
ChartUtilities.writeChartAsPNG(out, chart, 950, 350);
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


/** 
* 创建CategoryDataset对象

* @param xText x轴上的刻度
* @param xValue 数据
*/
public static CategoryDataset createDataset(String[] xText, float[] xValue) {
DefaultCategoryDataset categoryDataset = new DefaultCategoryDataset();
for (int i = 0; i < xText.length; i++) {
categoryDataset.addValue(xValue[i], "", xText[i]);
}
return categoryDataset;
}


/** 
* 根据CategoryDataset生成JFreeChart对象

* @param categoryDataset CategoryDatase对象
* @param t 图表名称
* @param x 横轴单位
* @param y 纵轴单位
* @param fontSize 字体大小
*/
public static JFreeChart createJFreeChart(CategoryDataset categoryDataset,
String t, String x, String y, int fontSize) {
JFreeChart jfreechart = ChartFactory.createBarChart(t, x, y,
categoryDataset, PlotOrientation.VERTICAL, true, false, false);


TextTitle textTitle = jfreechart.getTitle();
textTitle.setFont(new Font("宋体", Font.BOLD, 16));//标题


CategoryPlot plot = jfreechart.getCategoryPlot();


CategoryAxis domainAxis = plot.getDomainAxis();


/*------设置X轴坐标上的文字-----------*/
domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 9));


/*------设置X轴的标题文字------------*/
domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));


NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();


/*------设置Y轴坐标上的文字-----------*/
numberaxis.setTickLabelFont(new Font("宋体", Font.PLAIN,10));


/*------设置Y轴的标题文字------------*/
numberaxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));


numberaxis.setLabelAngle(Math.PI / 2);
//numberaxis.setVerticalTickLabels(true);
//numberaxis.setUpperBound(100);
//numberaxis.setLowerBound(0);
//底端legend不显示
jfreechart.getLegend().setVisible(false);
//设置网格背景颜色
plot.setBackgroundPaint(Color.white);
//设置网格横线颜色
plot.setRangeGridlinePaint(Color.pink);


return jfreechart;
}







 

}

数据模板

test_data_template.html

<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=gbk' />
<title></title>
<style type='text/css'>
body {
margin:0px  0px 0  10px;
padding:0px;
font-size: 12px;
font-family: SimSun;
}
table{border-collapse:collapse; }
.Tab{text-align:center;}
.Tab td{text-align:center;}
.Tab2{width:560px;height:310px; }
.Tab2 td{text-align:center;width:54px;}
.Tab3{table-layout:fixed;BORDER-BOTTOM:#ff39b1 2px solid;BORDER-RIGHT: #ff39b1 2px solid;BORDER-TOP:#ff39b1 2px solid;BORDER-LEFT:#ff39b1 2px solid;}
.tab4 td{ width:90%; font-size:12px;}


.fontC{
font-family:宋体;
font-size: 30px;
font-weight: bold;
}




</style>
</head>
<body>
<div style="height: 100%;width: 100%;margin-top: 0px;margin-left: 0px;">
<div style="height: 510px;width: 100%;overflow: auto;">
<div style="height: 50px;width: 100%;margin-top: 10px;">
<!-- 标题头 -->

<div align="center">
<div style="float: left;font-size:30px;font-weight: bold;">故障单111111111111111</div>
<div style="float: left;font-size:15px;">
<div style="margin-top: 15px;">
(待处理)
</div>
</div>
</div>

</div>

</div>
</div>
</body>
</html>

pdf模板

<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=gbk' />
<title></title>
<style type='text/css'>
body {
margin:0px  0px 0  10px;
padding:0px;
font-size: 12px;
font-family: SimSun;
}
table{border-collapse:collapse; }
.Tab{text-align:center;}
.Tab td{text-align:center;}
.Tab2{width:560px;height:310px; }
.Tab2 td{text-align:center;width:54px;}
.Tab3{table-layout:fixed;BORDER-BOTTOM:#ff39b1 2px solid;BORDER-RIGHT: #ff39b1 2px solid;BORDER-TOP:#ff39b1 2px solid;BORDER-LEFT:#ff39b1 2px solid;}
.tab4 td{ width:90%; font-size:12px;}


.fontC{
font-family:宋体;
font-size: 30px;
font-weight: bold;
}




</style>
</head>
<body>
<div style="height: 100%;width: 100%;margin-top: 0px;margin-left: 0px;">
<div style="height: 510px;width: 100%;overflow: auto;">
<div style="height: 50px;width: 100%;margin-top: 10px;">
<!-- 标题头 -->

<div align="center">
<div style="float: left;font-size:30px;font-weight: bold;">445678941</div>
<div style="float: left;font-size:15px;">
<div style="margin-top: 15px;">
(${transfer.countNum})
</div>
</div>
</div>

</div>
<!-- 判断为空如果为空则不显示  有数值则显示 -->
${transfer.onlineNum!''}






</div>
</div>
</body>
</html>

代码解决换行问题代码调用插入分行字符

/**
     * 插入方法
     * 
     * @param num
     *            每隔几个字符插入一个字符串(中文字符)
     * @param splitStr
     *            待指定字符串
     * @param str
     *            原字符串
     * @return 插入指定字符串之后的字符串
     * @throws UnsupportedEncodingException
     */
    public static String addStr(int num, String splitStr, String str) throws UnsupportedEncodingException {
        StringBuffer sb = new StringBuffer();
        String temp = str;

        int len = str.length();
        while (len > 0) {
            int idx = getEndIndex(temp, num);
            sb.append(temp.substring(0, idx + 1)).append(splitStr);
            temp = temp.substring(idx + 1);
            len = temp.length();
        }

        return sb.toString();
    }

    /**
     * 两个数字/英文
     * 
     * @param str
     *            字符串
     * @param num
     *            每隔几个字符插入一个字符串
     * @return int 最终索引
     * @throws UnsupportedEncodingException
     */
    public static int getEndIndex(String str, double num) throws UnsupportedEncodingException {
        int idx = 0;
        double val = 0.00;
        // 判断是否是英文/中文
        for (int i = 0; i < str.length(); i++) {
            if (String.valueOf(str.charAt(i)).getBytes("UTF-8").length >= 3) {
                // 中文字符或符号
                val += 1.00;
            } else {
                // 英文字符或符号
                val += 0.50;
            }
            if (val >= num) {
                idx = i;
                if (val - num == 0.5) {
                    idx = i - 1;
                }
                break;
            }
        }
        if (idx == 0) {
            idx = str.length() - 1;
        }
        return idx;
    }

猜你喜欢

转载自blog.csdn.net/cainiaochen3/article/details/80983367