java原装代码完成pdf在线预览和pdf打印及下载

前提准备:

1. 项目中至少需要引入的jar包,注意版本:

a) core-renderer.jar

b) freemarker-2.3.16.jar

c) iText-2.0.8.jar

d) iTextAsian.jar

上代码:

注释: 此类为自定义的Tag类的基类,在action中怎么放的数据,在ftl中就怎么取数据,简洁明了。

 1. 自定义Tag类的基类

 /**
 * 通用的生成pdf预览和生成打印的html文件
 *
 * @author xg君
 *
 */
public abstract class PDFTag extends BodyTagSupport {
 private static final long serialVersionUID = 1L;
 // 标签属性变量
 private String json = "";
 private String tempDir = "";
 // 非标签属性变量
 private Map<String, Object> rootMap = new HashMap<String, Object>();
 private String templateStr = null;
 private String freemarkereConfigurationBeanName = null;
 private String fileName = null;
 private String basePath = null;
 private String fileEncoding = "utf-8";
 @Override
 public int doStartTag() throws JspException {
 setConfigParams();
 WebApplicationContext application = WebApplicationContextUtils.getWebApplicationContext(pageContext
  .getServletContext());
 doServiceStart();
 String ctx = (String) pageContext.getAttribute("ctx");
 rootMap.put("ctx", ctx);
 Map<String, Object> map = parseJSON2Map(json);
 rootMap.putAll(map);
 if (freemarkereConfigurationBeanName == null) {
  try {
  throw new CstuException("FreemarkereConfigurationBeanName不能为空!");
  } catch (CstuException e) {
  e.printStackTrace();
  }
 }
 Configuration cptFreemarkereConfiguration = (Configuration) application
  .getBean(freemarkereConfigurationBeanName);
 try {
  if (templateStr == null) {
  throw new CstuException("模板文件不能为空!");
  }
  Template template = cptFreemarkereConfiguration.getTemplate(templateStr);
  if (basePath == null) {
  throw new CstuException("文件的基本路径(父路径)不能为空!");
  }
  File htmlPath = new File(tempDir + File.separator + basePath);
  if (!htmlPath.exists()) {
  htmlPath.mkdirs();
  }
  if (fileName == null) {
  throw new CstuException("生成的html文件名不能为空!");
  }
  File htmlFile = new File(htmlPath, File.separator + fileName);
  if (!htmlFile.exists()) {
  htmlFile.createNewFile();
  }
  BufferedWriter out = new BufferedWriter(
   new OutputStreamWriter(new FileOutputStream(htmlFile), fileEncoding));
  template.process(rootMap, out);
  out.flush();
  doServiceDoing();
  // 显示在页面
  template.process(rootMap, pageContext.getResponse().getWriter());
 } catch (Exception e) {
  e.printStackTrace();
 }
 doServiceEnd();
 return SKIP_BODY;
 }
 /**
 * 配置基础参数,如
 */
 public abstract void setConfigParams();
 /**
 * 业务处理方法-开始 填充数据
 *
 * @return
 */
 public abstract void doServiceStart();
 /**
 * 业务处理方法-执行中 备用,可空实现,若rootMap中存在双份数据则可在此处填充判断条件
 *
 * @return
 */
 public abstract void doServiceDoing();
 /**
 * 业务处理方法-结束 清空rootMap并调用垃圾回收,也可空实现
 *
 * @return
 */
 public abstract void doServiceEnd();

 /**
 * 将元素放入rootMap中
 */
 public void putKV(String key, Object value) {
 rootMap.put(key, value);
 }
 /**
 * 将map放入rootMap中
 *
 * @param m
 */
 public void putMap(Map m) {
 rootMap.putAll(m);
 }
 public void clear() {
 rootMap.clear();
 rootMap = null;
 }
 /**
 * 移除元素
 *
 * @param key
 * @return
 */
 public Object remove(String key) {
 return rootMap.remove(key);
 }
 public static Map<String, Object> parseJSON2Map(String jsonStr) {
 Map<String, Object> map = new HashMap<String, Object>();
 JSONObject json = JSONObject.fromObject(jsonStr);
 for (Object k : json.keySet()) {
  Object v = json.get(k);
  if (v instanceof JSONArray) {
  List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  Iterator<JSONObject> it = ((JSONArray) v).iterator();
  while (it.hasNext()) {
   JSONObject json2 = it.next();
   list.add(parseJSON2Map(json2.toString()));
  }
  map.put(k.toString(), list);
  } else {
  map.put(k.toString(), v);
  }
 }
 return map;
 }
 public String getJson() {
 return json;
 }
 public void setJson(String json) {
 this.json = json;
 }
 public String getTempDir() {
 return tempDir;
 }
 public void setTempDir(String tempDir) {
 this.tempDir = tempDir;
 }
 public String getTemplateStr() {
 return templateStr;
 }
 public void setTemplateStr(String templateStr) {
 this.templateStr = templateStr;
 }
 public String getFreemarkereConfigurationBeanName() {
 return freemarkereConfigurationBeanName;
 }
 public void setFreemarkereConfigurationBeanName(String freemarkereConfigurationBeanName) {
 this.freemarkereConfigurationBeanName = freemarkereConfigurationBeanName;
 }
 public String getFileName() {
 return fileName;
 }
 public void setFileName(String fileName) {
 this.fileName = fileName;
 }
 public String getBasePath() {
 return basePath;
 }
 public void setBasePath(String basePath) {
 this.basePath = basePath;
 }
 public String getFileEncoding() {
 return fileEncoding;
 }
 public void setFileEncoding(String fileEncoding) {
 this.fileEncoding = fileEncoding;
 }
}

注释: setConfigParams方法是用于调用接口定义的配置参数的方法,如:templateStr,basePath等,doServiceStart,doServiceDoing和doServiceEnd等方法用于处理业务逻辑,比如我的需求是做出合同在一个页面显示,要分页,要加水印,但生成的pdf样式与预览的是不同的,所以我加了一个doServiceDoing中给rootMap添加判断条件,这样就能一个flt文件作出两种效果(预览和打印),当然如果预览和打印要一样的效果,doServiceDoing方法可以空实现。这四个方法总结一下就是:

1. setConfigParams : 配置参数

2. doServiceStart : 填充数据/条件

3. doServiceDoing : 填充数据/条件,到这里是个分界线,此方法之前,rootMap数据先进入html再进入浏览器(预览),此方法之后,rootMap数据会再次进入html文件,结束,所以此处可写判断

4. doServiceEnd : 可有可无,我还是写上了,万一哪天的数据集太大,此处便可以在数据填充完后,清理掉,节省内存空间

2. PDFTag的子类

/**
 * 用户自定义PDFTag类
 *
 * @author xg君
 *
 */
public class ViewPDFTag extends PDFTag {
 private static final long serialVersionUID = 4528567203497016087L;
 private String prjNature = "";
 private String bookName = "";
 private String prjCode = "";
 /**
 * 用户自定义的配置参数
 */
 public PDFConfigurationInterface pDFConfigurationInterface = new PDFConfigurationInterface() {
 @Override
 public void configTemplateStr() {
  // 横,纵向
  if (prjNature.equalsIgnoreCase("2") || prjNature.equalsIgnoreCase("1")) {
  setTemplateStr("wj-project-print.ftl");
  }
 }
 @Override
 public void configFreemarkereConfigurationBeanName() {
  setFreemarkereConfigurationBeanName("cptFreemarkereConfiguration");
 }
 @Override
 public void configFileName() {
  // 填入html文件
  setFileName(prjCode + ".html");
 }
 @Override
 public void configFileEncoding() {
  // 默认utf-8
 }
 @Override
 public void configBasePath() {
  setBasePath("html_pdf");
 }
 };
 @Override
 public void doServiceStart() {
 putKV("prjNature", prjNature);
 putKV("bookName", bookName);
 putKV("flag", "0");
 }
 @Override
 public void doServiceDoing() {
 putKV("flag", "1");
 }
 @Override
 public void doServiceEnd() {
 clear();
 System.gc();
 }
 public String getPrjNature() {
 return prjNature;
 }
 public void setPrjNature(String prjNature) {
 this.prjNature = prjNature;
 }
 public String getBookName() {
 return bookName;
 }
 public void setBookName(String bookName) {
 this.bookName = bookName;
 }
 public String getPrjCode() {
 return prjCode;
 }
 public void setPrjCode(String prjCode) {
 this.prjCode = prjCode;
 }
 @Override
 public void setConfigParams() {
 pDFConfigurationInterface.configTemplateStr(); pDFConfigurationInterface.configFreemarkereConfigurationBeanName();
 pDFConfigurationInterface.configFileName();
 pDFConfigurationInterface.configBasePath();
 pDFConfigurationInterface.configFileEncoding();
 }
}

注释: PDFConfigurationInterface 是自定义的标签参数配置接口,子类必须定义一个该接口的实现类的成员变量或定义一个成员变量内部类,并在setConfigParams方法中调用使其生效。

子类的成员变量接收在tld文件中配置的属性。

3. 自定义的标签参数配置接口

/**
 * PdfTag类的配置
 *
 * @author xg君
 *
 */
public interface PDFConfigurationInterface {
 /**
 * 设置模板名称
 */
 void configTemplateStr();
 /**
 * 设置配置的FreemarkereConfigurationBean的名称
 */
 void configFreemarkereConfigurationBeanName();
 /**
 * 设置生成的html文件名称
 */
 void configFileName();
 /**
 * 设置生成的html文件的基本路径(父目录)
 */
 void configBasePath();
 /**
 * 设置文件编码,默认utf-8
 */
 void configFileEncoding();
}

4. 自定义异常类

/**
 * 自定义异常类
 *
 * @author Administrator
 *
 */
public class CstuException extends Exception {
 private static final long serialVersionUID = 4266461814747405870L;
 public CstuException(String msg) {
 super(msg);
 }
}

5. tld文件配置

<tag>
<name>print</name> <tagclass>com.iris.taglib.web.PreviewPDFTag</tagclass>
 <bodycontent>JSP</bodycontent>
 <attribute>
  <name>json</name>
  <required>true</required>
  <rtexprvalue>true</rtexprvalue>
 </attribute>
 <attribute>
  <name>prjNature</name>
  <required>true</required>
  <rtexprvalue>true</rtexprvalue>
 </attribute>
 <attribute>
  <name>bookName</name>
  <required>true</required>
  <rtexprvalue>true</rtexprvalue>
 </attribute>
 <attribute>
  <name>tempDir</name>
  <required>true</required>
  <rtexprvalue>true</rtexprvalue>
 </attribute>
 <attribute>
  <name>prjCode</name>
  <required>true</required>
  <rtexprvalue>true</rtexprvalue>
 </attribute>
 </tag>

6. action

/**
 * 处理PDF导出
 *
 */
@Namespace("/export")
@Results({ @Result(name = "exceltemplate", location = "/WEB-INF/content/pdf/export-pdf.jsp"),
 @Result(name = "exprotPdf2", location = "/WEB-INF/content/project/project/export/export-pdf2.jsp") })
public class ExportPdfAction extends ActionSupport {
 private static final long serialVersionUID = -5454188364706173477L;
 @Value("${tempDir}")
 private String tempDir;
 @Value("${pdfFont}")
 private String pdfFont;
 @Value("${staticResRootDir}")
 private String staticResRootDir;
 @Value("${staticResRootDir2}")
 private String staticResRootDir2;
 @Value("${WaterMarkImgDir}")
 private String waterMarkImgDir;
 @Autowired
 private ProjectService projectService;
 @Autowired
 private PersonService personService;
 @Autowired
 private ConstDictionaryService constDictionaryService;
 @Autowired
 private FdPlanDetailService fdPlanDetailService;
 @Autowired
 private ServiceFactory serviceFactory;
 @Action("exprotPdf2")
 public String exprotPdf2() {
 String prjCode = Struts2Utils.getParameter("prjCode");
 prjCode = Struts2Utils.decodeDesString(prjCode);
 Project project = projectService.getProjectById(Long.parseLong(prjCode));
 Map<String, String> baseInfo = new HashMap<String, String>();
 baseInfo.put("tempDir", tempDir);
 // 项目编号
 baseInfo.put("prjCode", prjCode);
 // 项目类型
 String prjNature = project.getPrjNature();
 baseInfo.put("prjNature", prjNature);
 // 水印名称格式:watermark+"-"+prjNature
 baseInfo.put("waterMarkImg", waterMarkImgDir + File.separator + "watermark-" + prjNature + ".png");
 // 负责人
 Person person = personService.getPerson(project.getPsnCode());
 String zhName = person.getZhName();
 baseInfo.put("zhName", addStr(9, "<br/>", zhName));
 // 项目编号
 String prjNo = project.getPrjNo();
 baseInfo.put("prjNo", prjNo);
 // 项目来源
 ConstDictionary cd = constDictionaryService.findCdByCategoryCode("project_from", project.getGrantNo());
 String project_from = cd.getzh_cn_caption();
 baseInfo.put("project_from", addStr(9, "<br/>", project_from));
 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 // 起止年限
 String startDate = sdf.format(project.getStartDate());
 String endDate = sdf.format(project.getEndDate());
 String startEndDate = startDate + "~" + endDate;
 baseInfo.put("startEndDate", startEndDate);
 // 项目类别--资助类别
 String grantName = project.getGrantName();
 baseInfo.put("grantName", addStr(9, "<br/>", grantName));
 // 合同金额
 String totalAmt = project.getTotalAmt().toString();
 BigDecimal totalAmt_ = checkNumber(totalAmt);
 baseInfo.put("totalAmt", totalAmt_.toString());
 // 项目名称
 String zhTitle = project.getZhTitle();
 baseInfo.put("zhTitle", addStr(38, "<br/>", zhTitle));
 List<Map<String, String>> ps = null;
 try {
  ps = getMembers(project.getPrjXml());
 } catch (Exception e) {
  e.printStackTrace();
 }
 String bookName = "";
 // 判断项目类型
 Map<String, Object> itemMap = new HashMap<String, Object>();
 if (prjNature.equalsIgnoreCase("1")) {
  bookName = "第一份合同";
  // 获取fdPlanDetail
  List<Map<String, Object>> list = fdPlanDetailService.getFdPlanDetailsByPrjCode(Long.parseLong(prjCode));
  // test
  /*
  * Map<String, Object> test = new HashMap<String, Object>(); test.put("itemValue", "6");
  * test.put("itemName", "差旅费"); test.put("remark", "xxxxx"); list.add(test);
  */
  for (Map<String, Object> m : list) {
  String key = (String) m.get("ITEMNAME");
  BigDecimal itemValue = (BigDecimal) m.get("ITEMVALUE");
  BigDecimal proportion = new BigDecimal(0.00);
  if (itemValue != null && totalAmt_.compareTo(new BigDecimal("0.00")) != 0) {
   proportion = itemValue.divide(totalAmt_, 6, BigDecimal.ROUND_HALF_EVEN);
  }
  if (itemValue == null) {
   itemValue = new BigDecimal("0.00");
  }
  proportion = checkNumber(proportion.toString());
  Map<String, Object> data = new HashMap<String, Object>();
  // 添加比例
  data.put("proportion", proportion.toString());
  // 检测金额规范
  BigDecimal amt = checkNumber(itemValue.toString());
  data.put("itemValue", amt.toString());
  // remark
  String remark = (String) m.get("REAMRK");
  data.put("remark", remark == null ? "" : remark);

  itemMap.put(key, data);
  }
 } else if (prjNature.equalsIgnoreCase("2")) {
  bookName = "第二份合同";
 }
 Map<String, Object> map = new HashMap<String, Object>();
 map.put("baseInfo", baseInfo);
 map.put("projectMember", ps);
 map.put("itemMap", itemMap);
 map.put("psCount", ps.size());
 map.put("psSum", 25 - ps.size());
 String json = JSONObject.fromObject(map).toString();
 Struts2Utils.getRequest().setAttribute("jsonData", json);
 Struts2Utils.getRequest().setAttribute("prjNature", prjNature);
 Struts2Utils.getRequest().setAttribute("bookName", bookName);
 Struts2Utils.getRequest().setAttribute("tempDir", tempDir);
 Struts2Utils.getRequest().setAttribute("prjCode", prjCode);
 return "exprotPdf2";
 }
 public List<Map<String, String>> getMembers(String xmlData) throws Exception {
 List<Map<String, String>> list = new ArrayList<Map<String, String>>();
 Document doc = DocumentHelper.parseText(xmlData);
 Node ps = doc.selectSingleNode("/data/project/persons");
 List<Node> psList = ps.selectNodes("person");
 String totalAmt = doc.selectSingleNode("/data/project/basic_info/total_amt").getText();
 for (Node person : psList) {
  Map<String, String> map = new HashMap<String, String>();
  Node fund_proportion = person.selectSingleNode("fund_proportion");
  String fund_proportion_text = "";
  if (fund_proportion == null) {
  map.put("proportion", "0.00");
  map.put("fpAmt", "0.00");
  } else {
  fund_proportion_text = fund_proportion.getText();
  BigDecimal fp = new BigDecimal(fund_proportion_text);
  fp = fp.multiply(new BigDecimal("0.01"));
  fp = checkNumber(fp.toString());
  map.put("proportion", fp.toString());
  BigDecimal fdAmt_ = fp.multiply(new BigDecimal(totalAmt));
  fdAmt_ = checkNumber(fdAmt_.toString());
  map.put("fpAmt", fdAmt_.toString());
  }
  Node psn_name = person.selectSingleNode("psn_name");
  String psn_name_text = psn_name.getText();
  map.put("zhName_p", addStr(9, "<br/>", psn_name_text));
  Node psn_work = person.selectSingleNode("psn_work");
  String psn_work_text = "";
  if (psn_work != null) {
  psn_work_text = psn_work.getText();
  }
  map.put("work", addStr(9, "<br/>", psn_work_text));
  Node dept_code_name = person.selectSingleNode("dept_code_name");
  String dept_code_name_text = "";
  if (dept_code_name != null) {
  dept_code_name_text = dept_code_name.getText();
  }
  map.put("deptName", addStr(9, "<br/>", dept_code_name_text));
  Node psn_type_name = person.selectSingleNode("psn_type_name");
  String psn_type_name_text = "";
  if (psn_type_name != null) {
  psn_type_name_text = psn_type_name.getText();
  }
  map.put("psnTypeName", psn_type_name_text);

  list.add(map);
 }
 return list;
 }
 /**
 * 为字符串添加指定字符
 *
 * @param num
 * @param splitStr
 * @param str
 * @return
 */
 public String addStr(int num, String splitStr, String str) {
 StringBuffer sb = new StringBuffer();
 String temp = str;
 int len = str.length();
 while (len > 0) {
  if (len < num) {
  num = len;
  }
  sb.append(temp.substring(0, num)).append(splitStr);
  temp = temp.substring(num);
  len = temp.length();
 }
 return sb.toString();
 }
 /**
 * 两个数字/英文
 *
 * @param str
 * @param num
 * @return 最终索引
 */
 public static int getEndIndex(String str, double num) {
 int idx = 0;
 int count = 0;
 double val = 0.00;
 // 判断是否是英文/数字
 for (int i = 0; i < str.length(); i++) {
  if ((str.charAt(i) >= 'A' && str.charAt(i) <= 'Z') || (str.charAt(i) >= 'a' && str.charAt(i) <= 'z')
   || Character.isDigit(str.charAt(i))) {
  val += 0.50;
  } else {
  val += 1.00;
  }
  count = i + 1;
  if (val >= num) {
  idx = i;
  break;
  }
 }
 if (idx == 0) {
  idx = count;
 }
 return idx;
 }
 /**
 * 下载pdf文件
 *
 * @return
 */
 @Action("downLoad")
 public String downLoad() {
 String prjCode = Struts2Utils.getParameter("prjCode");
 String basePath = "html_pdf";
 Project project = projectService.getProjectById(Long.parseLong(prjCode));
 String zhTitle = project.getZhTitle();
 FileOutputStream fos = null;
 // html
 File htmlFile = new File(tempDir + File.separator + basePath + File.separator + prjCode + ".html");
 String pdfPath = tempDir + File.separator + basePath + File.separator + zhTitle + ".pdf";
 try {
  fos = new FileOutputStream(pdfPath);

  String url = htmlFile.toURI().toURL().toString();
  ITextRenderer renderer = new ITextRenderer();
  renderer.setDocument(url);
  ITextFontResolver fontResolver = renderer.getFontResolver();
  fontResolver.addFont(pdfFont + File.separator + "SimSun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
  renderer.layout();
  renderer.createPDF(fos);
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
  try {
  if (fos != null) {
   fos.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
 }
 // 添加水印
 String wartermark = "";
 if (project.getPrjNature().equalsIgnoreCase("1")) {
  // 横向
  wartermark = "CTGU横向科研项目立项通知书";
 } else if (project.getPrjNature().equalsIgnoreCase("2")) {
  // 纵向
  wartermark = "CTGU纵向科研项目立项通知书";
 }
 String wm_pdf = tempDir + File.separator + "wm_" + project.getZhTitle() + ".pdf";
 try {
  BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(wm_pdf));
  waterMark(bos, pdfPath, wartermark, staticResRootDir2 + File.separator + waterMarkImgDir + File.separator
   + "watermark-" + project.getPrjNature() + ".png");
 } catch (Exception e2) {
  e2.printStackTrace();
 }
 // 拿到pdf
 File pdfFile = new File(wm_pdf);
 BufferedOutputStream out = null;
 FileInputStream in = null;
 try {
  in = new FileInputStream(pdfFile);
  HttpServletResponse response = Struts2Utils.getResponse();
  response.reset();
  String fileName = zhTitle + ".pdf";
  String fileName2 = URLEncoder.encode(fileName, "UTF-8");
  String agent = Struts2Utils.getRequest().getHeader("USER-AGENT");
  // IE
  if (null != agent && -1 != agent.indexOf("MSIE")) {
  fileName2 = new String(fileName.getBytes("GBK"), "ISO8859-1");
  } else if (null != agent && -1 != agent.indexOf("Mozilla")) {
  fileName2 = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
  }
  response.setCharacterEncoding("UTF-8");
  response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName2 + "\"");
  response.setContentType(FileContentTypes.getContentType(zhTitle + ".pdf"));
  out = new BufferedOutputStream(response.getOutputStream());
  byte[] buffer = new byte[16 * 1024];
  int len = 0;
  while ((len = in.read(buffer)) > 0) {
  out.write(buffer, 0, len);
  }
  out.flush();
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
  if (out != null) {
  try {
   out.close();
  } catch (IOException e1) {
   e1.printStackTrace();
  }
  try {
   in.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
  }
 }
 // 清理残留文件
 // if (htmlFile.exists()) {
 // htmlFile.delete();
 // }
 File temp_file = new File(pdfPath);
 if (temp_file.exists()) {
  temp_file.delete();
 }
 if (pdfFile.exists()) {
  pdfFile.delete();
 }
 return null;
 }
 public BigDecimal checkNumber(String number) {
 // 初始化为6位小数
 DecimalFormat df = new DecimalFormat("0.000000");
 String num = df.format(Double.parseDouble(number));
 BigDecimal bd = new BigDecimal(num);
 String val = bd.toString();
 val = val.replaceAll("^(0+)", "");
 val = val.replaceAll("(0+)$", "");
 int idx = val.indexOf(".");
 int len = val.substring(idx + 1).length();
 if (len < 2) {
  if (len == 0 && idx == 0) {
  bd = new BigDecimal("0.00");
  } else {
  bd = new BigDecimal(val).setScale(2);
  }
 } else {
  bd = new BigDecimal(val).setScale(len);
 }
 return bd;
 }
 private String replaceStr(String str, String reVal) {
 Pattern pattern = Pattern.compile("^" + reVal + "+|" + reVal + "+$");
 Matcher matcher = pattern.matcher(str);
 return matcher.replaceAll("");
 }
 /**
 * 添加水印
 */
 private void waterMark(BufferedOutputStream bos, String input, String waterMarkName, String imagePath) {
 try {
  PdfReader reader = new PdfReader(input);
  PdfStamper stamper = new PdfStamper(reader, bos);
  int total = reader.getNumberOfPages() + 1;
  PdfContentByte content;
  BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
  PdfGState gs = new PdfGState();
  for (int i = 1; i < total; i++) {
  content = stamper.getOverContent(i);// 在内容上方加水印
  content.setGState(gs);
  content.beginText();
  Image image = Image.getInstance(imagePath);
  image.setAbsolutePosition(-30, 200);
  image.scalePercent(80);
  content.addImage(image);
  content.endText();
  }
  stamper.close();
 } catch (Exception e) {
  e.printStackTrace();
 }
 }
}

7. ftl文件(模板文件)

<?xml version="1.0" encoding="UTF-8"?>
<!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>
 <title>打印预览</title>
 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
......
</head>
<body>
</body>
</html>

预览效果:

打印效果:

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • Java打印出所有的水仙花数的实现代码

    题目:打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指一个三位数,其各位数字立方和等于该数本身.例如:153是一个 "水仙花数 ",因为153=1的三次方+5的三次方+3的三次方. 程序分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位. 程序设计: public class exp2{ public static void main(String args[]){ int i=0; math mymath = new

  • 用Java打印九九除法表代码分析 原创

    可能你已经学会了如何在Java中用循环语句打印九九乘法表,但学习是一个需要能够举一反三的事情,接下来,我们就来看看如何使用for循环语句打印九九除法表. 代码(九九除法表): public class TestNineNine { public static void main(String[] args) { for(int b=1;b<=9;b++) { for(int a=1;a<=9;a++) { int c = a*b; System.out.print(c+"/"

  • Java利用for循环输出空心菱形的实例代码

    程序分析:先把图形分成两部分来看待,前四行一个规律,后三行一个规律,利用双重 for循环,第一层控制行,第二层控制列. 编写程序,在控制台上输出空心菱形,对角距离为6. public class Diamond { public static void main(String[] args) { printHollowRhombus(6); } public static void printHollowRhombus(int size) { if (size % 2 == 0) { size+

  • Java中异常打印输出的常见方法总结

    前言 Java异常是在Java应用中的警报器,在出现异常的情况下,可以帮助我们程序猿们快速定位问题的类型以及位置.但是一般在我们的项目中,由于经验阅历等多方面的原因,依然有若干的童鞋在代码中没有正确的使用异常打印方法,导致在项目的后台日志中,没有收到日志或者日志信息不完整等情况的发生,这些都给项目埋下了若干隐患.本文将深入分析在异常日志打印过程中的若干情况,并给出若干的使用建议. 1. Java异常Exception的结构分析 我们通常所说的Exception主要是继承于Throwable而来,

  • Java编程用指定字符打印菱形实例

    学习Java 本身是一个挺枯燥的过程,说白了就是每天敲代码而已.但如果换一种思路,可以编写各种各样的程序,不仅加深对代码的理解,同时提高兴趣,这样十分有利于大家的学习.下面我们来看一个有趣的小实例. 如何实现用指定字符打印出一个菱形,代码如下. import java.util.Scanner; import java.util.regex.Matcher; public class test01 { private static int i; private String ch; public

  • java原装代码完成pdf在线预览和pdf打印及下载

    前提准备: 1. 项目中至少需要引入的jar包,注意版本: a) core-renderer.jar b) freemarker-2.3.16.jar c) iText-2.0.8.jar d) iTextAsian.jar 上代码: 注释: 此类为自定义的Tag类的基类,在action中怎么放的数据,在ftl中就怎么取数据,简洁明了.  1. 自定义Tag类的基类 /** * 通用的生成pdf预览和生成打印的html文件 * * @author xg君 * */ public abstract

  • vue 使用 vue-pdf 实现pdf在线预览的示例代码

    背景 之前的demo增加了图片预览,于是今天下午追完番剧就突然想到能不能把pdf在线预览也做了,说干就干,刚开始查了很多教程,我发现很多人都在说什么pdf.js这个库,这当然没什么问题,pdf.js的确可以非常完美的实现pdf在线预览的过程,但是感觉这样直接进去有点不太优雅,于是找找看看有没有什么现成的组件,发现有vue-pdf这个组件,虽然说它没有原生那样强大,比如不支持pdf文字复制,打印会乱码,但是我感觉已经足以满足我的需求了.本篇笔记循序渐进,从基础的demo,到一个可用的程度,文末列出

  • Java实现PDF在线预览功能(四种方式)

    目录 Java实现PDF在线预览 Java快捷实现PDF在线预览 Java实现PDF在线预览 @RequestMapping("/preview1") public void er(HttpServletResponse response){ File file = new File("G:\\桌面\\Thymeleaf3.0中文翻译文档@www.java1234.com.pdf"); if (file.exists()){ byte[] data = null;

  • java通过jacob实现office在线预览功能

    简介: 这篇文章中的代码都是参考于网上的,只做一个记录.主要做的就是实现一个office在线预览功能. 第一步:装office 第二步:下载jacob 打开网址下载,目前最新的是1.19版本. 第三步:配置jdk 解压下载完的jacob压缩包,根据jdk的版本选择dll中的一个,放入/jdk/jre/bin中. 第四步:在项目中引入jar包 在maven官网上找不到com.jacob的jar包,只能手动引入,这个jar包在jacob的压缩包中有. <dependency> <groupI

  • Java实现办公文档在线预览功能

    java实现办公文件在线预览功能是一个大家在工作中也许会遇到的需求,网上些公司专门提供这样的服务,不过需要收费 如果想要免费的,可以用openoffice,实现原理就是: 通过第三方工具openoffice,将word.excel.ppt.txt等文件转换为pdf文件流: 当然如果装了Adobe Reader XI,那把pdf直接拖到浏览器页面就可以直接打开预览,前提就是浏览器支持pdf文件浏览. 我这里介绍通过poi实现word.excel.ppt转pdf流,这样就可以在浏览器上实现预览了.

  • Android实现pdf在线预览或本地预览的方法

    最近项目中需要使用在线预览pdf,并要能实现自动播放,我想这样的需求无论如何来说都是很操蛋的 由于本人水平有限,最后讨论将项目需求改成将pdf下载到本地再实现自动播放. 接下来总结下目前能够实现pdf阅读的方案,开发当中需要根据实际需求去选择相应的方案. 1.使用Google doc支持来展示word,excel,pdf,txt(WebView方式在线预览): <span style="font-size:18px;">WebView urlWebView = (WebVi

  • vue项目中常见的三种文件类型在线预览实现(pdf/word/excel表格)

    目录 前言 一.预览word文件 1.安装 npm 依赖 2.预览在线地址文件 3.预览本地文件 二.预览excel表格 1.安装依赖 2.预览在线表格 三.pdf预览 1.安装依赖vue-pdf 2.在需要的页面注册 3.使用 4.加载本地pdf文件 5.解决pdf使用自定义字体预览和打印乱码问题:pdfjsWrapper.js 总结 前言 之前做PDF预览一直用的pdf.js,这次没有太多附加需求比较简单简,所以决定用vue-pdf这个组件,虽然说它没有原生那样强大,但已经满足常用的需求了,

  • Java实现 word、excel文档在线预览

    java实现办公文件在线预览功能是一个大家在工作中也许会遇到的需求,网上些公司专门提供这样的服务,不过需要收费 如果想要免费的,可以用openoffice,实现原理就是: 通过第三方工具openoffice,将word.excel.ppt.txt等文件转换为pdf文件流: 当然如果装了Adobe Reader XI,那把pdf直接拖到浏览器页面就可以直接打开预览,前提就是浏览器支持pdf文件浏览. 我这里介绍通过poi实现word.excel.ppt转pdf流,这样就可以在浏览器上实现预览了.

  • 浅谈实现在线预览PDF的几种解决办法

    因客户需要实现PDF的预览处理,在网上找了一些PDF在线预览的解决方案,有的用PDFJS的在线预览方式,有的使用PDFObject的嵌入式显示,有的通过转换JPG/PNG方式实现间接显示的方式,开始是想通过简单的方式,能够使用JS插件实现预览最好,可是在线预览总是有一些不足,如不同浏览器的兼容问题,甚至不同的手机平台中展示的效果也不一样,不过最好还是采用了间接的方式,把PDF转换为图片展示效果,达到客户的要求. 1.在线实现预览的方式 一开始我还是很倾向使用这种方式,希望能采用一个较为好的JS插

  • Vue实现在线预览pdf文件功能(利用pdf.js/iframe/embed)

    前言 最近在做一个精品课程,需要在线预览课件ppt,我们的思路是将ppt转换为pdf在线预览,所以问题就是如何实现在线预览pdf了. 在实现的过程中,为了更好地显示效果,我采用了多种不同的方法,最终选择效果最好的pdf.js. 实现方法: 1:iframe 采取iframe将pdf嵌入网页从而达到预览效果,想法很美好,实现很简单,但显示很残酷- 虽然一行代码简洁明了,打开谷歌浏览器效果也还行,但缺点也是十分明显的!!!! <iframe src="http......" widt

随机推荐