java 导出html到pdf word

csdn不能上传附件,相关的代码包附带不上来,悲剧

 

html导出到pdf和word

导出到pdf
a) 解决问题:1、保留html的样式处理;2、解决中文问题
b) 处理描述:
对应html的处理,利用开源的包,flyingsaucer来进行处理,里面有所依赖的其他包
 InputStream input = new ByteArrayInputStream(out.toByteArray());
Document doc = builder.parse(input);
     ITextRenderer renderer = new ITextRenderer();
     renderer.setDocument(doc, null);
     renderer.layout();
     renderer.createPDF(os);
这里的input输入流要标准的xhtml,如果传如的html标签会有没有闭合或者属性上面的值没有““标注,需要进行格式化处理,继续利用开源的包jtidy.jar来处理:
Tidy tidy = new Tidy();
  tidy.setXmlOut(true);
  tidy.setXmlPi(true); // 添加 <?xml?> 标签 为输出的 XML 文件, 这些参数是可选的。
  tidy.setXmlSpace(true);
  tidy.setInputEncoding("utf-8");
  tidy.setOutputEncoding("utf-8");
  try {
   // 文件转换
   tidy.parse(inputStream, outStream);
  }catch (Exception e) {
   e.printStackTrace();
 }

样式的处理问题,如果在处理html标签的时候,没有找到相关的样式,renderer会有异常抛出,我的处理办法是直接将文档中的样式抽取出来,下面是我做的一个样式抽取处理,但是感觉不是很好,当每个控件上都有同样的样式时,就会做很多重复的工作,还有就是这里只抽取了class的样式:
function getStyleNode(htmlobj)
{
var link = document.getElementsByTagName("link");
    var style = document.getElementsByTagName("style");
    var htmlStr = [];
    htmlStr.push("<style>")
    getNodeStyles(link,htmlobj,htmlStr);
htmlStr.push("</style>")
return htmlStr.join(“”);
}

 


获取节点样式
getNodeStyles=function(link_files,htmlobj,returnArray)
{
 var className = htmlobj.className;
 if(!Ext.isEmpty(className))
 {
  var classNames = className.split(//s/);
  for(var c = 0 ; c < classNames.length ; c++)
  {
   var cls = "."+classNames[c].trim();
   if(cls.indexOf("selected")>=0)
    continue;
   returnArray.push(cls+"{")
   returnArray.push(dframe.getStyleValue(link_files,cls));
   returnArray.push("}");
  }
 }
 var chidlNodes = htmlobj.childNodes;
 for(var i = 0 ; i < chidlNodes.length ; i++)
 {
  getNodeStyles(link_files,chidlNodes[i],returnArray);
 }
}
获取样式值
getStyleValue=function(link_files,labname)
{
    var tar;
    var rss;
    var style;
    var value ="";
    tar = link_files;
    var queryFlag = false;
    for(var f = 0; f < link_files.length ; f++)
    {
     rss = tar[f].styleSheet.cssRules?tar[f].styleSheet.cssRules:tar[f].styleSheet.rules
       
  for(var i=0;i<rss.length;i++)
  {
   style = rss[i];
   if(style.selectorText.toLowerCase() == labname.toLowerCase())
   {
    value = style;
    queryFlag== true;
    break;
   }
  }
     if(queryFlag)
      break;
    }
    if(value != "")
      return value.style.cssText;
    return value;
}

最后的重头戏,解决中文问题:
  处理办法一、
flyingsaucer的帮助文档中的解说是在setDocument()之前来执行下面的代码,这样来处理UTF-8的编码问题:
import com.lowagie.text.pdf.BaseFont;

ITextRenderer renderer = new ITextRenderer();
FontResolver resolver = renderer.getFontResolver();
resolver.addFont (
"C://WINNT//Fonts//ARIALUNI.TTF",
BaseFont.IDENTITY_H,
BaseFont.NOT_EMBEDDED
);
这个不知道在其他人的机器上能不能解决中文问题,我电脑上的jdk的没有执行成功;

处理办法二、

这里需要另一个itext中文字体的包:iTextAsian.jar,可以打开看看,里面就是一些字体。
修改flyingsaucer中的源码:
找ITextFontOutputDevice中的
cb.setFontAndSize(_font.getFontDescription().getFont(), _font.getSize2D() / _dotsPerPoint);

 修改成:
try {         
cb.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",
BaseFont.NOT_EMBEDDED), _font.getSize2D()/_dotsPerPoint);         
        } catch (Exception e) { 
          e.printStackTrace();
        }
ok,重新编译,测试,中文正常显示。

遗留问题:
导出的文字不能自动换行,希望有深入研究的人相互交流。

 

 

利用poi导出word,这里不用做太多的处理,因为word就有打开html页面的功能,把输入的流出入即可:
ByteArrayInputStream bais = new ByteArrayInputStream(b);
      POIFSFileSystem poifs = new POIFSFileSystem();
      DirectoryEntry directory = poifs.getRoot();
      directory.createDocument("WordDocument", bais);
      poifs.writeFilesystem(os);
      bais.close();

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值