网上很多ttf转xml的文章,不多说
但是字体配置一节 是在<renderer mime="application/pdf"> 里面添加 <fonts> 的配置. 尝试了很多次,没有成功.
把<fonts>节点放在 <fop> 下即可 详见org.apache.fop.fonts.FontManagerConfigurator.configure() 79行
另外: <base>./</base> 是指项目根目录, 找不到字体,代码会报错
如果不报错,还是乱码,那么,配置未生效
<?xml version="1.0"?><fop version="1.0"><base>./</base> <source-resolution>72</source-resolution><target-resolution>72</target-resolution><default-page-settings height="11.00in"width="8.50in" /><fonts> <font metrics-url="HYShangWeiShouShuW-Regular.xml" embed-url="ad5b584b3ec5a50f74028a8e03080654.ttf"><font-triplet name="HYShangWeiShouShuW-Regular"style="normal" weight="normal" /><font-triplet name="HYShangWeiShouShuW-Regular"style="normal" weight="bold" /><font-triplet name="HYShangWeiShouShuW-Regular"style="italic" weight="normal" /><font-triplet name="HYShangWeiShouShuW-Regular"style="italic" weight="bold" /></font></fonts></fop>
// svg文件转成PDFpublic static void convert2Pdf(File svg, File pdf) {OutputStream outs = null;InputStream ins = null;try {File file = ResourceUtils.getFile("classpath:fop.xml");DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();cfg = cfgBuilder.buildFromFile(file); outs = new BufferedOutputStream(new FileOutputStream(pdf));ins = new FileInputStream(svg);PDFTranscoder transcoder = new PDFTranscoder();transcoder.configure(cfg); //配置.. 这里只是示例,不用每次都读...TranscoderInput input = new TranscoderInput(ins);TranscoderOutput output = new TranscoderOutput(outs);transcoder.transcode(input, output);} catch (Exception e) {e.printStackTrace();} finally {try {ins.close();outs.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
彩蛋: 简化配置
<?xml version="1.0"?><fop version="1.0"><base>./</base> <!-- Source resolution in dpi (dots/pixels per inch) for determining the size of pixels in SVG and bitmap images, default: 72dpi --><source-resolution>72</source-resolution><!-- Target resolution in dpi (dots/pixels per inch) for specifying the target resolution for generated bitmaps, default: 72dpi --><target-resolution>72</target-resolution><default-page-settings height="11.00in"width="8.50in" /><fonts><auto-detect/> <!-- 这就扫描系统字体了,我因为要管理字体,所以还是需要手工配置 --></fonts>
时隔一年... 把字体配置到数据库的方式一并放上来. 由于是定制项目,fop代码被我修改了不少,比如不支持svg中特殊字符,透明背景, cmyk单黑问题.
项目是一个印刷品在线编辑. 浏览器读取模板,在canvas中编辑排版,导出svg到后台,用fop转pdf这么个流程.前端用的fabricjs
------------------------------------------
fop配置文件中字体配置一项放进数据库.
1. 读取数据库配置到Configuration
@PostConstruct //必须在系统初始化,或者操作fop之前做public void init() {try {File file = ResourceUtils.getFile("classpath:fop.xml");log.debug("fop配置文件" + file.getAbsolutePath() + " , " + file.exists());DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();String generateFontXML = printingFontsService.generateFontXML(); //这里是读取数据库生成xml节点String conf = FileUtil.readString(file, "UTF-8");String source = StrUtil.format(conf, generateFontXML ); InputStream confStream = new StringInputStream(source, "UTF-8");cfg = cfgBuilder.build(confStream ); FopFactoryBuilder fopFactoryBuilder = new FopFactoryBuilder(new File(".").toURI()).setConfiguration(cfg);fac = fopFactoryBuilder.build(); log.debug("svgUtil inited");} catch (Exception e) {e.printStackTrace();}}
2. 读取数据库 代码
public String generateFontXML() throws Exception {List<PrintingFonts> allEntitys = this.getAllEntitys();StringBuilder sb = new StringBuilder();for (PrintingFonts f : allEntitys) {String fontname = f.getFontname();String md5 = EncryptUtil.MD5(fontname);// 注意,这里的 md5值是名称,实际操作下,发现有些中文,英文字体,自身有空格时,不生效.SVG属性中同样用这个md5作为font-family的值sb.append("<font kerning=\"yes\" embed-url=\"/data/fonts/"+f.getUuid()+".ttf\">\n" + " <font-triplet name=\""+ md5 +"\" style=\"normal\" weight=\"normal\" />\n" + " <font-triplet name=\""+ md5 +"\" style=\"normal\" weight=\"bold\" />\n" + " <font-triplet name=\""+ md5 +"\" style=\"italic\" weight=\"normal\" />\n" + " <font-triplet name=\""+ md5 +"\" style=\"italic\" weight=\"bold\" />\n" + " <font-triplet name=\""+ fontname +"\" style=\"normal\" weight=\"normal\" />\n" + " <font-triplet name=\""+ fontname +"\" style=\"normal\" weight=\"bold\" />\n" + " <font-triplet name=\""+ fontname +"\" style=\"italic\" weight=\"normal\" />\n" + " <font-triplet name=\""+ fontname +"\" style=\"italic\" weight=\"bold\" />\n" + "</font>\n");}return sb.toString();}
3. fop.xml
<?xml version="1.0"?><fop version="1.0"><base>./</base><target-resolution>300</target-resolution><default-page-settings height="11.00in"width="8.50in" /><!-- 动态上传字体并设置, 解决配置动态读取的问题 --><fonts> {} <!-- 占位符,数据库配置被放在这里 --><referenced-fonts><match font-family="Helvetica" /><match font-family="DejaVu.*" /></referenced-fonts><!-- <auto-detect /> --> <!-- 扫描系统字体 --></fonts><renderers><renderer mime="application/pdf"><filterList> <value>flate</value></filterList> <output-profile>/data/pdf_icc/PSO_LWC_Standard_bas.ICC</output-profile><pdf-x-mode>PDF/X-4</pdf-x-mode><!-- 符合印刷标准的pdf --><pdf-vt-mode>PDF/VT-1</pdf-vt-mode></renderer><renderer mime="application/postscript"></renderer><renderer mime="application/vnd.hp-PCL"></renderer></renderer> --><renderer mime="image/svg+xml"><format type="paginated" /><link value="true" /><strokeText value="false" /><images mode="color" cmyk="true"/></renderer><renderer mime="application/awt"></renderer><renderer mime="image/png"> <images mode="color" cmyk="true"/><color-mode>rgba</color-mode> </renderer><renderer mime="image/jpg"><images mode="color" cmyk="true"/></renderer><renderer mime="image/tiff"></renderer><renderer mime="text/xml"></renderer></renderers></fop>