PDF中的低质量使用KendoPDF在PDF中转换画布

PDF中的低质量使用KendoPDF在PDF中转换画布,pdf,canvas,report,kendo-ui-angular2,Pdf,Canvas,Report,Kendo Ui Angular2,我使用html画布创建了一个图表。结果希望它被打印成PDF文件使用剑道。它可以工作,但图形质量很差。对于我需要的解决方案,由于限制原因,我不能使用剑道图 report.html <div class="width-100-perc text-center"> <canvas id="canvas" width="100" height="100"></canvas> <br /> </div> 报告。ts dra

我使用html画布创建了一个图表。结果希望它被打印成PDF文件使用剑道。它可以工作,但图形质量很差。对于我需要的解决方案,由于限制原因,我不能使用剑道图

report.html

<div class="width-100-perc text-center">
    <canvas id="canvas" width="100" height="100"></canvas>
    <br />
</div>


报告。ts

drawChart() {
    console.log( 'foi');
    const canvas: HTMLCanvasElement = (<HTMLCanvasElement>document.getElementById('canvas'));
    console.log(this.series);
    if (canvas) {
        const ctx = canvas.getContext('2d');

        // Base offset distance of 10
        const offset = 0;
        let beginAngle = 0;
        let endAngle = 0;

        // Used to calculate the X and Y offset
        let offsetX, offsetY, medianAngle;

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fill();

        for (let i = 0; i < this.angles.length; i = i + 1) {
            beginAngle = endAngle;
            endAngle = endAngle + this.angles[i];

            // The medium angle is the average of two consecutive angles
            medianAngle = (endAngle + beginAngle) / 2;

            // X and Y calculations
            offsetX = Math.cos(medianAngle) * offset;
            offsetY = Math.sin(medianAngle) * offset;

            ctx.beginPath();
            ctx.fillStyle = this.series[0].data[i].color;

            // Adding the offsetX and offsetY to the center of the arc
            ctx.moveTo(50 + offsetX, 50 + offsetY);
            ctx.arc(50 + offsetX, 50 + offsetY, 40, beginAngle, endAngle);
            ctx.lineTo(50 + offsetX, 50 + offsetY);
            ctx.fill();
        }

        if (this.angles.length > 0) {
            ctx.beginPath();
            ctx.fillStyle = '#FFFFFF';
            ctx.arc(50, 50, 15, 0, 2 * Math.PI);
            ctx.fill();
        }
    }
}
drawChart(){
console.log('foi');
const canvas:htmlcanvaseElement=(document.getElementById('canvas');
console.log(this.series);
如果(画布){
const ctx=canvas.getContext('2d');
//基准偏移距离为10
常数偏移=0;
让beginAngle=0;
设端角=0;
//用于计算X和Y偏移
让offsetX,offsetY,medianAngle;
clearRect(0,0,canvas.width,canvas.height);
ctx.fill();
for(设i=0;i0){
ctx.beginPath();
ctx.fillStyle='#FFFFFF';
ctx.arc(50,50,15,0,2*Math.PI);
ctx.fill();
}
}
}

这不是剑道pdf导出的问题。相反,这是工作方式固有的。您的导出看起来扭曲和像素化,因为在一天结束时,它只是一个100x100的图像,分辨率相当低。我假设您希望它这么小,因为它是为了适合页面的特定部分而制作的。如果您只是直接导出此画布,那么像素化图像就是您所期望的

我可以提出这个解决办法。您需要重构
drawChart()
方法以考虑刻度(数字)。这意味着将所有x、y坐标和尺寸乘以该值。默认情况下,比例为1。导出为pdf时,您将执行以下步骤:

  • 将比例更改为更高的值,例如10
  • 导出为pdf
  • 再次将比例更改为1
  • 这样,图表将使用更高分辨率的画布临时重新绘制。在它的高(er)分辨率状态下,它被导出,然后用原始尺寸重新绘制

    如果您提供了
    this.angles
    this.series
    的一些示例值,我可以重构
    drawChart()
    函数来考虑这一点。就目前而言,我不能。但我准备了一个类似的例子。这是我创建的
    ReportComponent

    report.component.html

    <div class="width-100-perc text-center">
        <canvas id="canvas" width="100" height="100"></canvas>
        <br />
    </div>
    
    坏pdf
    好的pdf
    
    报告.component.ts

    drawChart() {
        console.log( 'foi');
        const canvas: HTMLCanvasElement = (<HTMLCanvasElement>document.getElementById('canvas'));
        console.log(this.series);
        if (canvas) {
            const ctx = canvas.getContext('2d');
    
            // Base offset distance of 10
            const offset = 0;
            let beginAngle = 0;
            let endAngle = 0;
    
            // Used to calculate the X and Y offset
            let offsetX, offsetY, medianAngle;
    
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.fill();
    
            for (let i = 0; i < this.angles.length; i = i + 1) {
                beginAngle = endAngle;
                endAngle = endAngle + this.angles[i];
    
                // The medium angle is the average of two consecutive angles
                medianAngle = (endAngle + beginAngle) / 2;
    
                // X and Y calculations
                offsetX = Math.cos(medianAngle) * offset;
                offsetY = Math.sin(medianAngle) * offset;
    
                ctx.beginPath();
                ctx.fillStyle = this.series[0].data[i].color;
    
                // Adding the offsetX and offsetY to the center of the arc
                ctx.moveTo(50 + offsetX, 50 + offsetY);
                ctx.arc(50 + offsetX, 50 + offsetY, 40, beginAngle, endAngle);
                ctx.lineTo(50 + offsetX, 50 + offsetY);
                ctx.fill();
            }
    
            if (this.angles.length > 0) {
                ctx.beginPath();
                ctx.fillStyle = '#FFFFFF';
                ctx.arc(50, 50, 15, 0, 2 * Math.PI);
                ctx.fill();
            }
        }
    }
    
    导出类ReportComponent实现AfterViewInit{
    @ViewChild(“画布”{static:false})
    公众谘询:ElementRef ;;
    @ViewChild(“pdf”{static:false})
    公共pdf:PDFExportComponent;
    @Input()公共标题:string=“”;
    公共规模:数量=1;
    公共基线宽度:数字=100;
    公共基线高度:数字=100;
    构造函数(){}
    ngAfterViewInit(){
    这个.draw();
    }
    画(){
    const canvas=this.canvasRef.nativeElement;
    canvas.width=this.baseWidth*this.scale;//已缩放
    canvas.height=this.baseHeight*this.scale;//已缩放
    const context=canvas.getContext(“2d”);
    const centerX=canvas.width/2;
    const centerY=canvas.height/2;
    常数半径=31.4*this.scale;//缩放
    context.beginPath();
    弧(centerX,centerY,半径,0,2*Math.PI,false);
    context.fillStyle=“绿色”;
    context.fill();
    context.lineWidth=5*this.scale;//已缩放
    context.strokeStyle=“#003300”;
    stroke();
    }
    savePdf(好:布尔值){
    如果(好){
    //缩放10倍并重新绘制
    这个比例=10;
    这个.draw();
    这个.pdf.saveAs(“good.pdf”);
    这个比例=1;
    这个.draw();
    }否则{
    //照原样画就行了
    这个.pdf.saveAs(“bad.pdf”);
    }
    }
    }
    

    坏PDF

    好的PDF文件

    您能否提供
    此.angles
    此.series
    的数据?是的,在我的情况下,这是一个动态值,直到一些示例值,以便我可以准备一些可复制的代码?